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的庫也不會被允許允許。