Android源码面试宝典之JobScheduler从使用到原理分析JobScheduler的使用
Posted itbird01
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android源码面试宝典之JobScheduler从使用到原理分析JobScheduler的使用相关的知识,希望对你有一定的参考价值。
我们之前总结过HandlerThread、IntentService,http://t.csdn.cn/U7Qzr,知道了,在子线程执行一些定时任务,android已经给我们提供了现成的一些API。但是我们也知道,这些
老的API
随着android的逐步发展,里面的很多漏洞逐渐被开发者们发现。SharePreference的ANR典型问题、HandlerThread的无限循环问题、IntentService仅有一个线程的局限性、AsyncTask的内存泄露问题等等,我们我们总是看到,随着每个android新版本的发布,看到sdk上面总是有各种废弃Deprecated
的字样。
本文,我们主要对IntentService的替代API接口JobScheduler,从简单的使用入手,然后逐步对内部的实现源码细节进行分析。
1. IntentService引入的背景
首先我们先看一下,android 8.0 之后,sdk中IntentService类的注释说明
/**
*这些主要是IntentService的使用说明,这里不再赘述,各位有兴趣的可以到小编专栏找相应的文章,查看
* IntentService is an extension of the @link Service component class that
* handles asynchronous requests (expressed as @link Intents) on demand.
* Clients send requests
* through @li
app 耗电优化之三 使用JobSchedule对任务进行合理排期
JobSchedule 是Android5.0之后添加进去的,之前的版本没有。
JobSchedule 原理是一种将任务安排在恰当的实际进行操作一种方案机制。具体提供了那些可选的时机,如下:
1 在可用网络下执行。在7.0 之前,应用可以通过监听网络变化来执行任务,当然了前提是应用必须存活。到7.0之后这类API已经失效,但是JobSchedule机制提供了网络变化的监听。进一步可以在网络变化的情况下执行某些操作。例如在wifi环境下执行下载任务等。
2 设备在充电或者空闲时执行一些任务。
3 设定执行的时间,这个和其他的条件(1,2)一起使用。
具体的实现如下:
1 任务排期
final JobScheduler scheduler = context.getSystemService(JobScheduler.class); //或者 final JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE ); //如果当前的jobId已经被安排了则下取消该安排 final int jobId = (int) info.mId; scheduler.cancel(jobId); //构建JobInfo jobId 为jobID。DownloadJobService 为Job接受的Service,该Service必须继承JobService final JobInfo.Builder builder = new JobInfo.Builder(jobId,new ComponentName(context, DownloadJobService.class)); //设置设备重启是执行此任务。前提是需要拥有RECEIVE_BOOT_COMPLETED 权限 builder.setPriority(JobInfo.PRIORITY_FOREGROUND_APP); //这个设置并不能设置成为前台进程。通知还需要应用自己发。此外该设置会忽略该任务的网络限制。 builder.setFlags(JobInfo.FLAG_WILL_BE_FOREGROUND); //设置任务延迟执行时间,不可与setPeriodic(long time)同时使用 builder.setMinimumLatency(time); //设置设备执行的网络条件JobInfo.NETWORK_TYPE_UNMETERED 不计量网络(wifi),JobInfo.NETWORK_TYPE_NOT_ROAMING 非漫游网络, NETWORK_TYPE_ANY任何网络 //JobInfo.NETWORK_TYPE_NONE 无论是否有网络都执行 builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); //设置在设备充电时执行 builder.setRequiresCharging(true); //设置在设备空闲时间执行 builder.setRequiresDeviceIdle(true); //循环没5秒执行一次 builder.setPeriodic(5000); //约定的时间内的条件都没有被触发是5秒以后开始触发 builder.setOverrideDeadline(5000); //生成Job JobInfo job = builder.build(); //安排Job,该方法有返回值JobScheduler.RESULT_SUCCESS 表示安排成功,JobScheduler.RESULT_FAILURE 安排失败 scheduler.schedule(job) //安排Job, packageName 表示那个应用安排的Job(耗电记这个应用的)。 userId表示谁安排的Job scheduler.scheduleAsPackage(builder.build(), packageName, UserHandle.myUserId(), TAG);
2 处理任务。
当任务安排下去,应该会被记录在JobScheduler服务里面。当条件满足时,处理job对应的JobService会被启动,否则。。。
首先定义JobService
<service android:name=".DownloadJobService" android:exported="true" //这个地方必须是True,否则外界的应用无法启动该JobService android:permission="android.permission.BIND_JOB_SERVICE" //必须定义这个权限,你懂得 />
public class DownloadJobService extends JobService { //开始执行Job接口。(必须实现)如果返回false则表示这个Job已经被执行完毕。如果true则表示这个Job正在被执行。 public boolean onStartJob(JobParameters params) { final int id = params.getJobId(); ....开始执行Job 1 对于一个瞬间能够完成的任务,此处可以return false. 2 如果是耗时任务,则需要在异步线程中执行,并且返回true。此外 myHandler.removeMessages(id); myHandler.sendEmptyMessage(id); 执行完后不要忘记执行jobFinished } //Job执行停止,必须实现 ,当接收到任务取消时,如果该任务没有被结束,则执行该方法,否则不执行。 public boolean onStopJob(JobParameters params) { //当然此处可以重新安排被取消的任务。 scheduler.schedule(job) } //还有一个方法。jobFinished(JobParameters params, boolean needsRescheduled) 该方法是在任务执行完成时通知系统(不代表任务被执行成功)。needsRecheduled表示该任务是否被重复执行。 //例如onStartJob执行结果是True。则实际上任务还在执行。这时候如果任务执行完了。就必须调用这个方法否则后面的任务。 }
总结,Scheduler是一套提供给开发者的一套优化耗电的任务安排方式,还是相当不错的。
以上是关于Android源码面试宝典之JobScheduler从使用到原理分析JobScheduler的使用的主要内容,如果未能解决你的问题,请参考以下文章
Android源码面试宝典之JobScheduler从使用到原理分析JobScheduler的使用