[译]Android 中的定时任务调度

在近期的应用开发中,异步执行任务是很流行的,而且这些任务经常在应用的生命周期之外运行,如下载数据或更新网络资源。有些情况下我们还需要做一些并不是马上需要执行的工作。Android 提供了一些 API 来帮助我们在应用中调度这些任务。

选择合适调度器可以提升应用的性能并且延长电池使用时间。

Android M 还引入了 打盹模式(Doze mode) 来减少用户在短期内不使用设备时的电池消耗。

Android 中可以使用的调度器有以下几种:

  • Alarm Manager
  • Job Scheduler
  • GCM Network Manager
  • Firebase Job Dispatcher
  • Sync Adapter

Services 的问题

Services 允许应用在后台执行长时间的操作, 但这一行为是十分耗电的。

当持续使用设备资源却没有有效任务在执行时,service 便更加有害了。当那些后台服务在监听不同系统广播时(比如 CONNECTIVITY_CHANGE 或者 NEW_PICTURE 等),问题的严重性还会提升。

在应用的生命周期之内调度任务

当应用正在运行时,如果我们想在特定时间执行任务的话,推荐使用 Handler 结合 Timer 和 Thread,而不是使用 Alarm Manger, Job Scheduler 等。使用 Handler 更简单高效。

在应用的生命周期之外调度任务

Alarm Manager

AlarmManager 提供系统级的定时服务。正因此,也是一种在应用生命周期之外执行操作的方法。即使应用没有运行,也可以触发事件或动作。AlarmManager 可以在未来唤起服务。当达到预定时间时,触发特定的 PendingIntent。

注册过的定时任务会在设备休眠时保留(并且可以选择是否唤醒设备),但在关机和重启时会被清空。

“我们应该只在执行特定时间的任务时使用 AlarmManager API。这并不是一个用来粗暴检查诸如设备空闲、网络状况或充电情况的方法。”

用例:假设我们想在一小时后执行任务或每隔一小时执行一次任务, AlarmManager 是完美选择。但这 API 并不适合执行特定条件的任务,如网络好或不充电时执行任务这种情况。

Job Scheduler

这是所有提过的调度器中最主要的一个,它可以高效地执行后台任务。 JobScheduler API 是在 Android 5.0(API level 21) 引入的

该 API 可以在资源充足时或满足条件时批量执行任务。创建任务时可以定义执行的先决条件。当条件满足时,系统会在应用的 JobService 上执行任务。 JobScheduler 的执行也取决于系统的打盹模式和应用当前状态。

批量执行的特性使得设备可以更快地进入休眠,并拥有更长的休眠期,以此来延长电池使用时间。总而言之,这个 API 可以用来执行任何对时间不敏感的计划。

GCM Network Manager

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 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

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) 上提供。

时间: 2024-10-12 09:23:35

[译]Android 中的定时任务调度的相关文章

Android中定时执行任务的3种实现方法

在Android开发中,定时执行任务的3种实现方法: 一.采用Handler与线程的sleep(long)方法(不建议使用,java的实现方式)二.采用Handler的postDelayed(Runnable, long)方法(最简单的android实现)三.采用Handler与timer及TimerTask结合的方法(比较多的任务时建议使用) 下面逐一介绍: 一.采用Handle与线程的sleep(long)方法 Handler主要用来处理接受到的消息.这只是最主要的方法,当然Handler里

Android中仿淘宝首页顶部滚动自定义HorizontalScrollView定时水平自动切换图片

Android中仿淘宝首页顶部滚动自定义HorizontalScrollView定时水平自动切换图片 自定义ADPager 自定义水平滚动的ScrollView效仿ViewPager 当遇到要在ViewPager中添加多张网络请求图片的情况下,不能进行复用,导致每次都要重新去求情已经请求过的数据致使流量数据过大 自定义的数据结构解决了这个问题,固定传递的图片数据之后进行统一请求,完成后进行页面切换数据复用 代码中涉及网络请求是用的Volley网络请求框架 PicCarousel是网络数据请求的U

python中的轻量级定时任务调度库:schedule

提到定时任务调度的时候,相信很多人会想到芹菜celery,要么就写个脚本塞到crontab中.不过,一个小的定时脚本,要用celery的话太“重”了.所以,我找到了一个轻量级的定时任务调度的库:schedule. 库的安装还是最简单的pip install schedule,使用起来也是很容易理解的.我们从最简单的栗子看起: import schedule import time def job(): print("I'm working...") schedule.every(10)

项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送邮件 5.基于poi实现分区导出

1 Shiro整合ehCache缓存授权信息 当需要进行权限校验时候:四种方式url拦截.注解.页面标签.代码级别,当需要验证权限会调用realm中的授权方法   Shiro框架内部整合好缓存管理器,整合ehcache环境,只需要配置即可.     <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>

【译】Android中构建快速可靠的UI测试

博客原地址:Android中构建快速可靠的UI测试 译文原链接:Fast and reliable UI tests on Android 翻译:Anthony 译者注:如果你关注android架构,那么你肯定之前看过小鄧子翻译的这篇文章Android应用架构.本篇文章的正是其原作者Iván Carballo的又一篇经典之作.也推荐你关注github项目Android架构合集以及我的从零开始搭建android框架系列文章 前言 让我一起来看看 Iván Carballo和他的团队是如何使用Esp

Android基础入门教程——8.1.3 Android中的13种Drawable小结 Part 3

Android基础入门教程--8.1.3 Android中的13种Drawable小结 Part 3 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来把剩下的四种Drawable也学完,他们分别是: LayerDrawable,TransitionDrawable,LevelListDrawable和StateListDrawable, 依旧贴下13种Drawable的导图: 1.LayerDrawable 层图形对象,包含一个Drawable数组,然后按照数组对应的顺序来

Android基础入门教程——8.1.2 Android中的13种Drawable小结 Part 2

Android基础入门教程--8.1.2 Android中的13种Drawable小结 Part 2 标签(空格分隔): Android基础入门教程 本节引言: 本节我们继续来学习Android中的Drawable资源,上一节我们学习了: ColorDrawable:NinePatchDrawable: ShapeDrawable:GradientDrawable!这四个Drawable~ 而本节我们继续来学习接下来的五个Drawable,他们分别是: BitmapDrawable:Insert

Android中检查、监听电量和充电状态的方法

Android中检查.监听电量和充电状态的方法 这篇文章主要介绍了Android中检查.监听电量和充电状态的方法,如判断当前充电状态.监听充电状态的改变.判断当前剩余电量等,需要的朋友可以参考下 当你在更改后台更新频率来减少这些更新对电池寿命的影响时,检查当前电量和充电状态是一个好的开始. 电池寿命通过剩余电量和充电状态来影响应用更新的执行.当用交流电充电时,执行更新操作对设备的影响是微不足道的,所以在大多数案例里,你可以把更新频率调到最快.如果设备不在充电,降低更新频率可以帮助延长电池寿命.

Spring整合Quartz实现定时任务调度

一. 核心类 1. Job: 表示一个工作, 具体的业务处理都在这里. 2. JobDetail: 表示一个具体的可执行的调度程序. 3. Trigger: 用于调度参数的配置(什么时候去调用Job). 4. Scheduler: 表示一个调度容器, 容器中有一个线程池, 用来并行调度执行每个作业, 一个调度容器中可以注册多个JobDetail和Trigger. 二. 整合spring 1. 代码结构图: 2. applicationContext.xml <?xml version="1