【Kotlin x Android】JobSchedulerを用いたバックグラウンド処理

今回は、Androidでのバックグラウンド処理に関する話です。

1. Androidのバックグラウンド処理

Android は、8.0 Oreoより、バックグラウンド処理の制限が強化されています。
参考:バックグラウンド実行制限 – Android Developers

これにより、Serviceなどで完全にバックグラウンドの処理を行っているアプリは、
修正が必要になってきます。

2. Service

Androidには従来から,「Service」というバックグラウンドで何かしらの
処理を行うための仕組みが従来からあります。
これは非常に有用なのですが、常にスマートフォンのバッテリー消費問題のやり玉にあげられてきました。

OS側でも、不用意なバックグラウンド処理は避けるような方向で
進んできていたのですが、今回(8.0)はかなり大きく制限された感じです。

3. JobScheduler

上記のドキュメント内にも何度か出てきますが、
代替案として「JobScheduler」が使用できます。
ということで、
「ボタンを押すと、約5秒後にToast 通知が表示される」サンプルを作ってみました。

環境:Android Studio 3.0.1
targetSdkVersion 26
minSdkVersion 24 (実機が Nougat しかなかったので…)

まずは、JobServiceを継承したクラスを作成します。

MyJobService.kt

import android.app.job.JobParameters
import android.app.job.JobService
import android.widget.Toast

class MyJobService : JobService() {
    override fun onStartJob(p0: JobParameters?): Boolean {
        Toast.makeText(this,"My Job Service",Toast.LENGTH_SHORT).show()
        return false;
    }
    override fun onStopJob(p0: JobParameters?): Boolean {
        return false;
    }
}

続いて、サービスを登録するためのAndroidManifestの記述です。

AndroidManifest.xml

    <service android:name=".MyJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:enabled="true" android:exported="false">
  </service>

最後に、メインのActivityです。

MainActivity.kt

// inport省略
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        val mName: ComponentName = ComponentName(this, MyJobService::class.java)
        val intent: Intent = Intent(this,MyJobService::class.java)
        startService(intent)

        button.setOnClickListener { view ->
            val scheduler: JobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
            val jobInfo: JobInfo = JobInfo.Builder( 0, mName)
                    .setMinimumLatency(5000)
                    .setOverrideDeadline(10000)
                    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
                    .build();
            scheduler.schedule(jobInfo)
        }
    }

    // 以下省略
}

こんな感じで、バックグラウンド処理を実装できます。

ちなみに

上記のサンプルでは、Toastが出るのは1回きりです。
では続けて行うにはどうするかというと、
MainActivityのJobInfoの設定を、下記のように書き換えると行えます。

        button.setOnClickListener { view ->
            val scheduler: JobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
            val jobInfo: JobInfo = JobInfo.Builder( 0, mName)
                    .setPeriodic(5000)
                    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
                    .build();
            scheduler.schedule(jobInfo)

ところが、
上記では5秒間隔設定なのですが、実際にはその通りに動作しません。
どうもAndroidの仕様で、ある一定時間以下にはできないようです。
上記では、自動的に15分おきに変わってしまいます…

どうすればいいんでしょう…

Share

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Optionally add an image (JPEG only)