1. 程式人生 > >APP開發實戰164-Evernote的JobScheduler方案

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