Android系统分析之JobScheduler源码分析

1 调用流程

这里写图片描述

2 源码分析

 /**
     * JobScheduler实体抽象类
     */
    abstract class JobScheduler {
        //定义接口方法
        schedule(JobInfo job);

        cancel(int jobId);
    }

    /**
     * JobScheduler实体实现类
     */
    class JobSchedulerImpl extends JobScheduler {

        IJobScheduler mBinder;

        JobSchedulerImpl(IJobScheduler binder) {
            mBinder = binder;
        }
    }


/**
 * aidl:是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口.
 * 以下文件用于:系统框架层进程 与 应用程序层进程 进程间通信
 */

    /**
     * 进程1-aidl接口文件:IJobScheduler.aidl
     */
    interface IJobScheduler {
        //定义接口方法
        schedule(JobInfo job);

        cancel(int jobId);
    }

    /**
     * 进程2-aidl接口文件:IJobService.aidl
     */
    interface IJobService {
        //定义接口方法
        schedule(JobInfo job);

        cancel(int jobId);
    }

    /**
     * 系统框架层
     * IPC接口:IJobScheduler接口
     */
    interface IJobScheduler extends IInterface {

        abstract class Stub

        ()extends Binder implements IJobScheduler

        {
            Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

            //接口原生方法

        static IJobScheduler asInterface(IBinder obj);

        schedule(JobInfo job);

        cancel(int jobId);
    }
}

/**
 * 应用程序层
 * IPC接口:IJobService接口
 * 这接口用于系统框架 与 实现JobService方法的应用程序代码通信。最终用户代码不直接实现此接口; 使用时(JobService),应用程序的服务实现将扩展IJobService。
 */
interface IJobService extends IInterface {

    abstract class Stub()extends Binder implements IJobService {
        Stub() {
        this.attachInterface(this, DESCRIPTOR);
    }

        //接口原生方法

    static IJobService asInterface(IBinder obj);//将IBinder对象转换为android.app.job.IJobService接口,如果需要,生成代理。

    schedule(JobInfo job);

    cancel(int jobId);
}
}


/**
 * 核心类
 * 系统框架层服务-JobSchedulerService
 */
class JobSchedulerService extends SystemService {

    public JobSchedulerService(Context context) {
        super(context);
        // Create the controllers.控制器
        mControllers = new ArrayList<StateController>();
        mControllers.add(ConnectivityController.get(this));//wifi\蜂窝控制器
        mControllers.add(TimeController.get(this));//超时时间
        mControllers.add(IdleController.get(this));//idle
        mControllers.add(BatteryController.get(this));//充电情况

        mHandler = new JobHandler(context.getMainLooper());
        mJobSchedulerStub = new JobSchedulerStub();
        mJobs = JobStore.initAndGet(this);
    }

    class JobSchedulerStub extends IJobScheduler.Stub {//实现IJobScheduler接口

        schedule(JobInfo job) {//实现接口方法
            JobSchedulerService.schedule(JobInfo job, int uId);
        }

        schedule(JobInfo job, int uId) {
            JobStatus jobStatus = new JobStatus(job, uId);
            cancelJob(uId, job.getId());
            startTrackingJob(jobStatus);//当有一个工作状态对象进入时,我们需要插入JobStore,并确保所有相关的控制器知道此事开始监听&反应。
            mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();//***1.handler发送MSG_CHECK_JOB执行排队准备执行Jobs消息
            return JobScheduler.RESULT_SUCCESS;
        }

        cancel(int jobId);
    }

    class JobHandler extends Handler {
        void handleMessage(Message message) {
            switch (message.what) {
                case MSG_JOB_EXPIRED:
                    break;
                case MSG_CHECK_JOB:
                    maybeQueueReadyJobsForExecutionLockedH();//***2.排队准备执行Jobs
                    break;
            }
            maybeRunPendingJobsH();//***4.执行延迟工作(PendingJobs)
        }
    }

    //排队准备执行Jobs方法
    private void maybeQueueReadyJobsForExecutionLockedH() {
        int chargingCount = 0;
        int idleCount = 0;
        int backoffCount = 0;
        int connectivityCount = 0;
        List<JobStatus> runnableJobs = new ArrayList<JobStatus>();
        ArraySet<JobStatus> jobs = mJobs.getJobs();
        for (int i = 0; i < jobs.size(); i++) {
            JobStatus job = jobs.valueAt(i);
            if (isReadyToBeExecutedLocked(job)) {//对job的控制状态判断并添加到runnableJobs
                if (job.getNumFailures() > 0) {
                    backoffCount++;
                }
                if (job.hasIdleConstraint()) {
                    idleCount++;
                }
                if (job.hasConnectivityConstraint() || job.hasUnmeteredConstraint()) {
                    connectivityCount++;
                }
                if (job.hasChargingConstraint()) {
                    chargingCount++;
                }
                runnableJobs.add(job);
            } else if (isReadyToBeCancelledLocked(job)) {
                stopJobOnServiceContextLocked(job);//停止
            }
        }
        if (backoffCount > 0 || idleCount >= MIN_IDLE_COUNT || connectivityCount >= MIN_CONNECTIVITY_COUNT ||
                chargingCount >= MIN_CHARGING_COUNT || runnableJobs.size() >= MIN_READY_JOBS_COUNT) {
            for (int i = 0; i < runnableJobs.size(); i++) {
                mPendingJobs.add(runnableJobs.get(i));//***3.添加到延迟工作(PendingJobs)中
            }
        }
    }

    //执行延迟工作(PendingJobs)
    private void maybeRunPendingJobsH() {
        synchronized (mJobs) {
            Iterator<JobStatus> it = mPendingJobs.iterator();
            if (DEBUG) {
                Slog.d(TAG, "pending queue: " + mPendingJobs.size() + " jobs.");
            }
            while (it.hasNext()) {
                JobStatus nextPending = it.next();
                JobServiceContext availableContext = null;//****5.1 调用JobServiceContext类启用onServiceConnected()方法执行延迟工作方法
                for (int i = 0; i < mActiveServices.size(); i++) {
                    JobServiceContext jsc = mActiveServices.get(i);
                    final JobStatus running = jsc.getRunningJob();
                    if (running != null && running.matches(nextPending.getUid(), nextPending.getJobId())) {

                        availableContext = null;
                        break;
                    }
                    if (jsc.isAvailable()) {
                        availableContext = jsc;
                    }
                }
                if (availableContext != null) {
                    if (!availableContext.executeRunnableJob(nextPending)) {//***5.2 判断JobServiceContext的job是否执行
                        mJobs.remove(nextPending);
                    }
                    it.remove();
                }
            }
        }
    }
}

/**
 * 处理客户端绑定和生命周期的工作。 乔布斯的一个实例上执行一次类。有两个重要的交互类的JobSchedulerService。执行工作,取消工作。
 */
class JobServiceContext extends IJobCallback.Stub implements ServiceConnection {

    /**
     * 我们获取/释放wakelock
     */
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        if (!name.equals(mRunningJob.getServiceComponent())) {
            mCallbackHandler.obtainMessage(MSG_SHUTDOWN_EXECUTION).sendToTarget();
            return;
        }

        this.service = IJobService.Stub.asInterface(service);//6.建立连接获取Job服务:IJobService.Stub.asInterface

        final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);//获取/释放WakeLock
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mRunningJob.getTag());
        mWakeLock.setWorkSource(new WorkSource(mRunningJob.getUid()));
        mWakeLock.setReferenceCounted(false);
        mWakeLock.acquire();
        mCallbackHandler.obtainMessage(MSG_SERVICE_BOUND).sendToTarget();//Handler发送消息MSG_SERVICE_BOUND
    }

    private class JobServiceHandler extends Handler {
        JobServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
                case MSG_SERVICE_BOUND:
                    removeOpTimeOut();
                    handleServiceBoundH();***7.执行handleServiceBoundH()方法
                    break;
            }
        }

        /**
         * 在服务中开启执行job.
         */
        private void handleServiceBoundH() {
            service.startJob(mParams);//********8.终点,startJob()开启执行方法   ———0
        }

        //检查如果工作是有效的,正在运行。 假如果工作不能被执行。
        boolean executeRunnableJob(JobStatus job) {

            return true;
        }
    }

    /**
     * 应用程序层服务-JobService
     */
    class JobService extends Service {

        //使用时,应用程序的服务实现将扩展JobService
        static final class JobInterface extends IJobService.Stub {//实现IJobService接口

            startJob();

            stopJob();
        }

        IJobService mBinder;
    }

    /**
     * 应用测试-TestJobService
     */
    class TestJobService extends JobService {

        //关键代码-开启JobScheduler
        public void scheduleJob(JobInfo t) {
            JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
            tm.schedule(t);//JobSchedulerService
        }


        //关键代码-执行耗时操作
        boolean onStartJob(JobParameters params) {//********0.起点,startJob()开启执行方法 ———8
            jobParamsMap.add(params);
            if (mActivity != null) {
                mActivity.onReceivedStartJob(params);

                //执行耗时操作:下载文件———


            }
            return false;
        }

        //停止操作
        boolean onStopJob(JobParameters params) {
            // Stop tracking these job parameters, as we've 'finished' executing.
            jobParamsMap.remove(params);
            if (mActivity != null) {
                mActivity.onReceivedStopJob();
            }
            return true;
        }

    }

    /**
     * 系统进程
     * 开启系统后Zygote进程(Linux核心)启动系统进程SystemServer,开启一些列的关键服务:AMS/PMS/WMS/JobSchedulerService
     */
    class SystemServer {
        mSystemServiceManager.startService(JobSchedulerService.class);//通过反射启动Service并添加到Service集合中(864行)
    }

    /**
     * Context/ContextImpl 在系统框架层与应用程序层进程间绑定Binder,实现进程间通信
     */
    class ContextImpl {

        //开启服务
        startService(Intent service) {
            return startServiceCommon(service, mUser);
        }

        startServiceCommon(Intent service, UserHandle user) {
            ComponentName cn = ActivityManagerNative.getDefault().startService(mMainThread.getApplicationThread(), service,
                    service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
            return cn;
        }
    }


    /**
     * 应用程序层,服务端:调用服务
     */
    class TestJobService extends JobService {

        JobScheduler jobs = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);//获取系统进程getSystemService = JobSchedulerService. JobSchedulerStub

        jobs.schedule(t);//调用接口方法
    }

    /**
     * 应用程序层,客户端:调用服务
     */
    class MainActivity extends Activity {
        onCreate(Bundle savedInstanceState) {
            //开启服务
            Intent startServiceIntent = new Intent(this, TestJobService.class);
            startServiceIntent.putExtra("messenger", new Messenger(mHandler));
            startService(startServiceIntent);//要求给定应用程序服务启动
        }

    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值