APP開發實戰164-Evernote的JobScheduler方案
34.13.2 JobScheduler的替代方案
前面提到,使用JobScheduler時,即使執行任務的條件不滿足,任務也會被執行;為了規避這個缺陷,可以使用Evernote提供的庫讓APP定期執行任務,以下是具體的實現方式。
在build.gradle檔案中增加庫的依賴:
dependencies {
…
compile 'com.evernote:android-job:1.1.8'
}
需要從庫提供的類派生幾個類:
public class DemoJobCreator implementsJobCreator {
@Override
public Job create(String tag) {
switch (tag) {
case DemoSyncJob.TAG:
return new DemoSyncJob();
default:
return null;
}
}
}
public class DemoSyncJob extends Job {
public static final String TAG ="job_demo_tag";
@Override
@NonNull
protected Result onRunJob(finalParams params) {
if (params.isPeriodic()) {
PendingIntent pendingIntent =PendingIntent.getActivity(getContext(), 0, new Intent(getContext(),MainActivity.class), 0);
Notification notification =new NotificationCompat.Builder(getContext())
.setContentTitle("JobDemo")
.setContentText("Periodic job run")
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_notifications_black_24dp)
.setShowWhen(true)
.setColor(Color.GREEN)
.setLocalOnly(true)
.build();
NotificationManagerCompat.from(getContext()).notify(newRandom().nextInt(), notification);
EamLog.v("job","isPeriodic==true");
}else {
EamLog.v("job","isPeriodic==false");
}
return Result.SUCCESS;
}
}
需要在Application類中建立類的例項:
public class EamApplication extendsApplication {
private static Context sContext;
@Override
public void onCreate() {
super.onCreate();
…
JobManager.create(this).addJobCreator(new DemoJobCreator());
}
}
//Job的任務Id
private int mLastJobId;
private JobManager mJobManager;
//初始化JobManager物件
public void initVariables() {
…
mJobManager = JobManager.instance();
}
//設定執行此任務需滿足的條件、間隔時間和關機重啟後是否繼續執行
public static void scheduleJob(){
mLastJobId = newJobRequest.Builder(DemoSyncJob.TAG)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.setPeriodic(JobRequest.MIN_INTERVAL)
.setPersisted(true)
//設定只有此任務的執行條件被滿足時,才執行此任務
.setRequirementsEnforced(true)
.build()
.schedule();
}
//取消Job
private void cancelJob(){
mJobManager.cancelAll();
}
Evernote提供了setRequirementsEnforced函式,讓使用者設定是否只有任務執行的條件都滿足了,系統才執行任務。
在Android7.0中,Job迴圈執行時,最小的間隔時間是15分鐘,所以Evernote為了相容Android7.0,設計任務迴圈執行的最新間隔時間也是15分鐘。
在Evernote提供的原始碼(JobRequest.java)中,可以看到如下說明:
/**
* The minimum interval of a periodicjob. Specifying a smaller interval will result in an exception.
* This limit comes from the {@codeJobScheduler} starting with Android Nougat.
*/
public static final long MIN_INTERVAL =TimeUnit.MINUTES.toMillis(15);
使用這個庫時,在混淆檔案中要增加如下程式碼:
-dontwarn com.evernote.android.job.gcm.**
-dontwarncom.evernote.android.job.util.GcmAvailableHelper
-keep public classcom.evernote.android.job.v21.PlatformJobService
-keep public classcom.evernote.android.job.v14.PlatformAlarmService
-keep public classcom.evernote.android.job.v14.PlatformAlarmReceiver
-keep public classcom.evernote.android.job.JobBootReceiver
-keep public classcom.evernote.android.job.JobRescheduleService
34.13.3 注意事項
1上述兩種方案都必需在Android5.0(API 21)及以上的系統中使用。
2從Android6.0開始,為了省電,Android實現了低耗電模式:通過在裝置長時間處於閒置狀態時推遲應用的後臺 CPU 和網路 Activity 來減少電池消耗;在此模式下系統不允許執行 JobScheduler。
Evernote提供的庫繼承了JobScheduler功能類,所以在低耗電模式下,Evernote的庫也不會被允許允許。