- 原文地址:Schedule tasks and jobs intelligently in Android
- 原文做者:Ankit Sinhal
- 译文出自:掘金翻译计划
- 译者:PhxNirvana
- 校对者:ilumer、wilsonandusa
在近期的应用开发中,异步执行任务是很流行的,并且这些任务常常在应用的生命周期以外运行,以下载数据或更新网络资源。有些状况下咱们还须要作一些并非立刻须要执行的工做。Android 提供了一些 API 来帮助咱们在应用中调度这些任务。html
选择合适调度器能够提高应用的性能而且延长电池使用时间。前端
Android M 还引入了 打盹模式(Doze mode) 来减小用户在短时间内不使用设备时的电池消耗。java
Android 中可使用的调度器有如下几种:react
Services 容许应用在后台执行长时间的操做, 但这一行为是十分耗电的。android
当持续使用设备资源却没有有效任务在执行时,service 便更加有害了。当那些后台服务在监听不一样系统广播时(好比 CONNECTIVITY_CHANGE 或者 NEW_PICTURE 等),问题的严重性还会提高。 ios
当应用正在运行时,若是咱们想在特定时间执行任务的话,推荐使用 Handler 结合 Timer 和 Thread,而不是使用 Alarm Manger, Job Scheduler 等。使用 Handler 更简单高效。git
AlarmManager 提供系统级的定时服务。正所以,也是一种在应用生命周期以外执行操做的方法。即便应用没有运行,也能够触发事件或动做。AlarmManager 能够在将来唤起服务。当达到预约时间时,触发特定的 PendingIntent。github
注册过的定时任务会在设备休眠时保留(而且能够选择是否唤醒设备),但在关机和重启时会被清空。后端
“咱们应该只在执行特定时间的任务时使用 AlarmManager API。这并非一个用来粗暴检查诸如设备空闲、网络情况或充电状况的方法。”api
用例:假设咱们想在一小时后执行任务或每隔一小时执行一次任务, AlarmManager 是完美选择。但这 API 并不适合执行特定条件的任务,如网络好或不充电时执行任务这种状况。
这是全部提过的调度器中最主要的一个,它能够高效地执行后台任务。 JobScheduler API 是在 Android 5.0(API level 21) 引入的
该 API 能够在资源充足时或知足条件时批量执行任务。建立任务时能够定义执行的先决条件。当条件知足时,系统会在应用的 JobService 上执行任务。 JobScheduler 的执行也取决于系统的打盹模式和应用当前状态。
批量执行的特性使得设备能够更快地进入休眠,并拥有更长的休眠期,以此来延长电池使用时间。总而言之,这个 API 能够用来执行任何对时间不敏感的计划。
GCM (Google Cloud Messaging) Network Manager 有着 JobScheduler 的所有特性,GCM Network Manager 也用在重复的或一次性的,不紧急的任务上来延长电量。
这个 API 是向下兼容的,支持 Android 5.0 (API level 21) 如下。从 API level 23 开始,GCM Network Manager 使用 Android 框架的 JobScheduler。GCM Network Manager 使用 Google Play 服务 内置的调度器,因此这个类 只会在安装了 Google Play 服务 的设备上运行。
Google 强烈建议 GCM 的用户升级到 FCM 并使用 Firebase Job Dispatcher 执行任务调度。
Firebase JobDispatcher 也是一个后台任务调度库。该库也被用来向下支持(低于 API level 21)而且支持全部近期 Android 设备(API level 9+)。
这个库也能够在没有安装 Google play 服务的设备,却仍想调度任务的应用上使用。这时,库内部的实现是 AlarmManager。若是设备上有 Google Play 服务,则会使用 Google Play 服务内置的调度器。
提示: 当 Google Play 服务不可用时,会使用 AlarmManager 来支持 API level <= 21
若是设备是 API level 21 的话,则使用 JobScheduler。这个库的框架是相同的,因此没有什么功能改变。
Sync adapter 是被特别设计用来同步设备和云端数据的。它的用途也只限定在这方面。同步能够在云端或客户端数据有改变时触发,也能够经过时间差或设定每日一次。Android 系统会试图执行批量同步来节省电量,没法同步的将会被放到队列中稍后执行。系统只在联网时会尝试执行同步。
无论什么状况,都建议使用 Google 提供的 JobScheduler、Firebase JobDispatcher、或 GCM Network Manager。
在 Android N (API level 24)中,SyncManager 在 JobScheduler (任务)的顶端。若是须要 SyncAdapter 提供的额外功能的话,建议只使用 SyncAdapter。
咱们已经讨论了一堆理论性的东西,下面来看看如何使用 Android job scheduler。
1. 创建 Job Service
创建 JobSchedulerService 并继承 JobService 类,须要重写下面两个方法:onStartJob(JobParameters params) 和 onStopJob(JobParameters params)
public class JobSchedulerService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;
}
}复制代码
onStartJob(JobParameters params) 方法在 JobScheduler 决定执行任务时调用。JobService 在主线程工做,因此任何耗时操做都应该在另外的线程执行。onStopJob(JobParameters params) 在任务还没执行完(调用 jobFinished(JobParameters, boolean) 以前),但系统决定中止执行时调用。
还须要在 AndroidManifest 中注册 job service
复制代码
2. 建立 JobInfo 对象
创建 JobInfo 对象须要将 JobService 传递到 JobInfo.Builder() 中,以下所示。这个 job builder 容许设置不一样选项来控制任务的执行。
ComponentName serviceName = new ComponentName(context, JobSchedulerService.class);
JobInfo jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.build();复制代码
3. 调度任务
如今有了 JobInfo 和 JobService ,因此是时候来调度任务了。 用 JobInfo 调度任务时只须要执行以下代码便可:
JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
int result = scheduler.schedule(jobInfo);
if (result == JobScheduler.RESULT_SUCCESS) {
Log.d(TAG, “Job scheduled successfully!”);
}复制代码
能够在 GitHub 下载 JobSchedulerExample 的源码
当调度任务时,须要仔细考虑执行的时间和条件,以及出错的后果。须要在应用性能和其余电池之类的条件间取舍。
JobScheduler 容易实现,而且处理了大多数的复杂状况。当使用 JobScheduler 时,即便系统重启咱们的任务依旧能够执行下去。此刻,JobScheduler 惟一的缺点就是它最低只在 api level 21 (Android 5.0) 上提供。
感谢阅读。若是感受有用,还请轻点❤来推荐文章给更多人。
关注接下来的文章。有任何意见和建议请经过下面的渠道联系咱们: TwitterGoogle+LinkedIn
进入个人 博客 获取更多有趣的开发话题。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、React、前端、后端、产品、设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划。