来源
JobSchedule类是从Android 5开始的,已经是快三年前的东西了,最开始提出这个东西,Google的目的是为了节省电量,关于节电部分的讨论,可以移步知乎的一个话题帖 link。
总体上说,这个提出的意义就是将一些不合适的设备唤醒行为进行统一管理,达到省电的目的。
广播
所谓的“隐式广播”
应该并没有显示广播隐式广播的官方说法,使用 显示Intent 发送的就是显示广播,使用 隐式Intent 发送的就是隐式广播。
广播接收器的静态注册、动态注册
在Manifest文件中声明的就是静态注册,代码中通知Context的API进行注册的就是动态注册。静态注册的广播接收器可以在APP进程处于非活状态下,接受广播并激活程序(启动进程)。
鉴于这些特性,有些APP中利用静态注册的形式,监听了一系列系统广播(这些都是通过隐式Intent发出的)。但是,这是比较费电的,举个例子:监听系统新消息广播,提取短信验证码。
这是一个比较常见的需求,一般来说,这个“监听”的生命期应该从调用webservice发出短信开始到相关的Activity结束,但是不排除部分程序员将其做成静态注册的广播接收器。类似的还有网络状态变更的监听(这也是一个很典型的例子,而且更容易设计成静态注册的广播接收器)。
这一系列行为使得我们的APP在不需要监听的情况下也进行了监听,甚至是APP进程没有起的情况下,一旦收到广播通知,APP进程就会启动,可能一些依赖网络的信息同步任务、ping包测试、日志统计模块会运行,无形中增加了耗电,但这些是没有意义的。
所以、JobSchedule设计的目的,有一方面是为了减少不合理的静态注册的系统广播接收器。
Android N中的变化
我们知道Android O已经正式发布了,但国内使用Android N的还只有三成,L、M、N形成了三分天下,而且我们知道在去年发布的Android N已经取消了针对三项系统广播的接收器的静态注册的支持。分别是:
- CONNECTIVITY_ACTION 广播
- ACTION_NEW_PICTURE广播
- ACTION_NEW_VIDEO 广播
Android O中的变化
Android O彻底移除了静态注册系统广播的接收器。
其实这是一个很好的改变,意味着我们有更好的方案来优雅的实习需求,毕竟广播是一个重量级的家伙。而且,在此之前,可能你有使用一些方案实现了需求,但在Android O中将不再受到支持,所以是时候把JobSchedule拿出来再细看看了。
JobSchedule的相关说明
先摘录一段Java doc
/**
* This is an API for scheduling various types of jobs against the framework that will be executed
* in your application's own process.
* <p>
* See {@link android.app.job.JobInfo} for more description of the types of jobs that can be run
* and how to construct them. You will construct these JobInfo objects and pass them to the
* JobScheduler with {@link #schedule(JobInfo)}. When the criteria declared are met, the
* system will execute this job on your application's {@link android.app.job.JobService}.
* You identify which JobService is meant to execute the logic for your job when you create the
* JobInfo with
* {@link android.app.job.JobInfo.Builder#JobInfo.Builder(int,android.content.ComponentName)}.
* </p>
* <p>
* The framework will be intelligent about when you receive your callbacks, and attempt to batch
* and defer them as much as possible. Typically if you don't specify a deadline on your job, it
* can be run at any moment depending on the current state of the JobScheduler's internal queue,
* however it might be deferred as long as until the next time the device is connected to a power
* source.
* </p>
* <p>You do not
* instantiate this class directly; instead, retrieve it through
* {@link android.content.Context#getSystemService
* Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)}.
*/
大体说来,包含以下几点信息:
- 运行在APP进程中
- 处理多种类型的任务
- 任务使用JobInfo进行描述
- 需要创建一个JobService,它是Service的子类
- 任务的调度是比较灵活的,系统会选择合适的时机处理一批累积的任务
- JobInfo JobSchedule 的实例化方式
再看一看其源码
public abstract class JobScheduler {
/**
* Returned from {@link #schedule(JobInfo)} when an invalid parameter was supplied. This can occur
* if the run-time for your job is too short, or perhaps the system can't resolve the
* requisite {@link JobService} in your package.
*/
public static final int RESULT_FAILURE = 0;
/**
* Returned from {@link #schedule(JobInfo)} if this job has been successfully scheduled.
*/
public static final int RESULT_SUCCESS = 1;
/**
* @param job The job you wish scheduled. See
* {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
* you can schedule.
* @return An int representing ({@link #RESULT_SUCCESS} or {@link #RESULT_FAILURE}).
*/
public abstract int schedule(JobInfo job);
/**
*
* @param job The job to be scheduled.
* @param packageName The package on behalf of which the job is to be scheduled. This will be
* used to track battery usage and appIdleState.
* @param userId User on behalf of whom this job is to be scheduled.
* @param tag Debugging tag for dumps associated with this job (instead of the service class)
* @return {@lin