こんにちは、KID.Aです。
最近、Camera周りの記事が多かったため、ここら辺で違う記事を書こうと思います。
ちょっと古いですが、API Level 21(L)から追加されたJobSchedulerの記事になります。
Android開発者ならおそらく知っていると思いますが、API Level 21(L)から追加されたJobSchedulerというものがあります。
開発サイトのAPI
https://developer.android.com/intl/ja/reference/android/app/job/JobScheduler.html
Lから追加されておりますが、サポートライブラリーなどに組み込まれておらず2.3や4.0から対応させているアプリ開発者はあまり使う機会ないというのが現状だと思います。
ただMがリリースされてこれからKitkat以前のバージョンが減ってきたらJobSchedulerが使える機会が増えてくると思います。今回はJobSchedulerに慣れようということで簡単な概要や使い方を記載しようと思います。
・JobSchedulerとは?
Project Volta(簡単にいうとGoogleのバッテリーの省電力プロジェクト)がバッテリーを長くするために提供したAPIです。開発者はJobSchedulerで消費電力を意識した実装ができます。
JobSchedulerは色々な種類のジョブをスケジュールしてくれるAPIです。
設定した種類の条件と端末の状態があっていればジョブを実行してくれます。
また実行遅延やリトライ間隔などの細かな設定もできます。
どのような設定ができるか見てみましょう。
メソッド名 | 説明 |
---|---|
setBackoffCriteria | back-off/retryのポリシーを設定できます。retry時間を2、4、8など遅れさせることができます。 |
setMinimumLatency | 実行前の遅延時間を設定することができます。 |
setExtras | PersistableBundleを設定できます。 |
setOverrideDeadline | スケジュールの最大遅延時間を設定することができます。 |
setPeriodic | 数回実行する場合に、実行間隔を設定することができます。 |
setPersisted | デバイス再起動後もタスクを実行するかどうかを設定できます。アプリがRECEIVE_BOOT_COMPLETED権限がなければ効果がありません。 |
setRequiredNetworkType | ネットワークが必要かどうかを設定できます。ネットワークが必要な場合は、ネットワークが利用できない状況でタスクは実行されません。 |
setRequiresCharging | デバイスを電源に接続している必要があるか設定できます。デフォルトは必要なしに設定されています。 |
setRequiresDeviceIdle | アイドルモード上で動作するか設定できます。アイドルモードでは、デバイスが使用されていない状態で、使用されていないかどうかはシステムが定義しています。 |
かなり細かい動作ができますね。
それでは実際に動かしてみましょう。
以下はボタンを押下したらJobScheduler経由でトーストがでるサンプルコードになります。
まずはJobServiceを継承したサービスを作ります。
・MyJobService.java
public class MyJobService extends JobService { @Override public boolean onStartJob(JobParameters params) { new ToastTask().execute(params); return true; } @Override public boolean onStopJob(JobParameters params) { return false; } private class ToastTask extends AsyncTask<JobParameters, Void, String> { protected JobParameters mJobParam; @Override protected String doInBackground(JobParameters... params) { mJobParam = params[0]; return String.valueOf(mJobParam.getJobId()); } @Override protected void onPostExecute(String result) { jobFinished(mJobParam, false); Toast.makeText(MyJobService.this, "job id = " + result, Toast.LENGTH_SHORT).show(); } } }
ボタンをつけたactivityを作ります。(単純なボタンでよいのでlayout.xmlは省きます)
・MainActivity.java
public class MainActivity extends AppCompatActivity { ComponentName mServiceName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mServiceName = new ComponentName(this, MyJobService.class); Intent intent = new Intent(this, MyJobService.class); startService(intent); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); for (int i = 0; i < 2; i++) { JobInfo jobInfo = new JobInfo.Builder(i, mServiceName) .setMinimumLatency(3000) .setOverrideDeadline(60000) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build(); scheduler.schedule(jobInfo); } } }); } }
AndroidManifestに以下のように記載しいます。
Serviceにはandroid.permission.BIND_JOB_SERVICEが必要です。
・AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package=“jp.co.jobscheduler" > <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" /> </application> </manifest>
簡単に一連の流れを説明すると、
- JobInfo.BuilderでJobInfoオブジェクトを作成します
- JobSchedulerに渡して実行します
- MyJobServiceのonStartJobが呼ばれます
- jobFinishedを呼ぶとMyJobServiceのonStopJobが呼ばれます
になります。
今回のアプリではJobInfo.Builderで以下の設定をしています。
・setMinimumLatency(3000)⇒実行時間を3秒遅らせる
・setOverrideDeadline(60000)⇒ジョブの最大遅延時間60秒
・setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)⇒ネットワークが有効のときに実行する
ボタンを押下してから、3秒後にトーストがでると思います。
また、setRequiredNetworkTypeがJobInfo.NETWORK_TYPE_ANYにしているのでネットワークを有効にしていないとボタンを押下してもトーストがでないです。
ネットワークが無効の状態で、ボタンを押下後にネットワークを有効にすると60秒の期間内であればタスクが実行されてトーストがでます。
状態によってジョブを実装の可否を自動的に判定してくれます。これで不要な処理を実行させないことにより省電力につなげることができるはずです。
省電力を意識することはユーザにとってよいし、その分(マーケットや顧客に)指摘される心配も少なくなるので開発者にとってもよいことです。
もしLから対応するアプリであれば使うのを考えるのもよいと思います。