上一篇文章:JobScheduler(一)——JobScheduler的使用
1.JobScheduler框架简述
在上一篇文章中,对怎样使用JobScheduler做了一个简单的总结,当客户端应用通过JobScheduler.schedule(JobInfo)
方法将创建的Job发送给JobScheduler后,Framework层将完全负责它的启动、执行、完成等生命周期调度。从这篇文章开始,将对JobScheduler框架层的源码及其实现原理进行分析。
整个JobScheduler框架类结构如下图所示:
橙色代表暴露给应用层的API
从图中来看,整个JobScheduler框架还是挺复杂的,图中各类说明如下:
JobScheduler
:暴露给客户端的接口类,它是一个抽象类,通过getSystemService()
获取实例;JobSchedulerImpl
:JobScheduler的具体实现类,客户端实际拿到的是该类实例,其中携带一个Binder实例,将调用进入JobSchedulerService;JobInfo
:暴露给客户端的用于创建Job的类,封装了创建Job时所设置的所有信息;JobService
:继承于Service,客户端需要JobService的子类来执行任务;JobSchedulerService
:继承于SystemService的系统服务,负责调度所有的Job;JobStatus
:Framework层内部表示Job的唯一标识,通过JobInfo创建,其中存储了所有的Job信息;JobStore
:负责维护JobSchedulerService正在跟踪的Job的列表,还支持一些遍历Job、读写文件等操作(将job信息写入/data/system/job/jobs.xml中)。在获取JobStore实例时,通过单例模式保证JSS只持有一个该类对象;StateController
:状态控制器的基类,每个子类控制器单独负责控制一个系统状态,当状态发生变化后,将通知JobSchedulerService进行处理;StateChangedListener
:状态控制器的回调接口,所有控制器通过该接口来通知JobSchedulerService;JobServiceContext
:继承于ServiceConnection,负责和应用的JobService绑定和作业生命周期管理。此类的一个实例上只能执行一个作业。JobServiceEngine
:应用端的JobService和JobSchedulerService进行交互的"引擎",帮读一个客户端Service后,将由该类去调用客户端的onStartJob()
方法开始执行任务;JobCompletedListener
:作业执行完毕后的回调接口。
针对整个框架的实现原理,可以简单地这样描述: 首先通过JobScheduler创建一个Job,接着JobSchedulerService
将负责调度job,经过各种StateController
对其进行跟踪,当满足条件后,将通过JobServiceContext
和客户端JobService
进行绑定并对Job进行生命周期管理,然后在生命周期的某个阶段中通过JobServiceEngine
调用客户端方法来执行Job任务,执行完成后,又在生命周期的某个阶段回调JobCompletedListener
接口通知JobSchedulerService
。
2.JobSchedulerService的启动
JobSchedulerService(以下简称JSS)是一个系统服务,它是SystemService的子类,因此,当系统开机后,SystemServer中将会启动它,并依次执行它的生命周期方法。
2.1.SystemServer中启动JSS
当SystemServer进程启动以后,将在startOtherService()
中开始启动JobSchedulerService:
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored
* and organized.
*/
private void startOtherServices() {
//...
mSystemServiceManager.startService(JobSchedulerService.class);
//...
}
进入到mSystemServiceManager中,将通过反射方式获得一个JobSchedulerService实例,并调用SystemService生命周期方法中的onStart()
:
/**
* Creates and starts a system service. The class must be a subclass of
* {@link com.android.server.SystemService}.
*
* @param serviceClass A Java class that implements the SystemService interface.
* @return The service instance, never null.
* @throws RuntimeException if the service fails to start.
*/
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
// Create the service.
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
//获得JobSchedulerService实例
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
//......
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
public void startService(@NonNull final SystemService service) {
// 加入到List<SystemService>集合中
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
//调用onStart()方法
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
}
从以上代码中可以得知,首先会执行JobSchedulerService的构造方法,之后将执行其onStart()
方法,除此之外,随着SystemServer的启动,最终还会执行其onBootPhase(int)
,这个方法表示启动阶段,根据参数每调用一次该方法,表示启动到了一个阶段。比如:
private void startOtherServices() {
//......
//表示核心系统服务已经启动完毕,可以放心使用了
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
//到这个阶段时,表示服务可以启动或绑定到应用程序了,应用程序也将可以通过Binder调用SystemService进程了
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
//......
}
接下来,我们就进入JobSchedulerService中,根据它的启动流程,依次分析其构造方法、onStart()
和onBootPhase()
方法。
2.2.Constructor()方法
首先来看其构造方法:
public JobSchedulerService(Context context) {
super(context);
//获取本地PackManagerService内部类对象(只能在system_server进程使用)
mLocalPM = LocalServices.getService(PackageManagerInternal.class);
//获取本地ActivityManagerService内部类对象
mActivityManagerInternal = Preconditions.checkNotNull(
LocalServices.getService(ActivityManagerInternal.class));
//实例化Handler,并使用当前进程主线程Looper
mHandler = new JobHandler(context.getMainLooper());
//实例化Constants,其中定义了许多常量
mConstants = new Constants();
//实例化内容观察者对象
mConstantsObserver = new ConstantsObserver(mHandler);
//实例化JobSchedulerStub对象,将发布到系统服务中,作为Binder的服务端
mJobSchedulerStub = new JobSchedulerStub();
//实例化StandbyTracker,用于记录appStandby信息
mStandbyTracker = new StandbyTracker();
//获取本地USageStatsService内部类对象
mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class)