Android 9.0 JobScheduler(二) JobScheduler框架结构简述及JobSchedulerService的启动

上一篇文章:JobScheduler(一)——JobScheduler的使用

1.JobScheduler框架简述

在上一篇文章中,对怎样使用JobScheduler做了一个简单的总结,当客户端应用通过JobScheduler.schedule(JobInfo)方法将创建的Job发送给JobScheduler后,Framework层将完全负责它的启动、执行、完成等生命周期调度。从这篇文章开始,将对JobScheduler框架层的源码及其实现原理进行分析。

整个JobScheduler框架类结构如下图所示:
JSS类图

橙色代表暴露给应用层的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)
  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值