今回は、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分おきに変わってしまいます…
どうすればいいんでしょう…