android JobService相关源码分析

  1. 放入任务
    1.1 getSystemService的过程

    JobScheduler scheduler = (JobScheduler) this.getSystemService(Context.JOB_SCHEDULER_SERVICE);//这里的this是Activity
    scheduler.schedule(jobInfo); //jobInfo持有JobService 的实现

    frameworks/base/core/java/android/app/ContextImpl.java

    public Object getSystemService(String name) {
        return SystemServiceRegistry.getSystemService(this, name);
    }

    frameworks/base/core/java/android/app/SystemServiceRegistry.java

    public Object getSystemService(String name) {
        ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
        return fetcher == null ? null : fetcher.getService(this);
    }

    public Object getService(ContextImpl ctx) {
        service = createService(ctx); //如果cache里不存在,就调用createService来创建
    }

    registerService(JOB_SCHEDULER_SERVICE, new ServiceFetcher() {
        public Object createService(ContextImpl ctx) {
             IBinder b = ServiceManager.getService(JOB_SCHEDULER_SERVICE);  //b其实是mJobSchedulerStub
             return new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b)); //也就是说getSystemService获得的最终是JobSchedulerImpl
        }
    }

    frameworks/base/core/java/android/app/JobSchedulerImpl.java

    JobSchedulerImpl(IJobScheduler binder) {
        mBinder = binder;
     }
    
    public int schedule(JobInfo job) {
        try {
            return mBinder.schedule(job); //也就是说通过JobScheduler调用schedule方法,其实就是调用mBinder的schedule方法
        } catch (RemoteException e) {
            return JobScheduler.RESULT_FAILURE;
        }
    }

    1.2 ServiceManager.getService(JOB_SCHEDULER_SERVICE)过程解析
    frameworks/base/core/java/android/os/ServiceManager.java

    public static IBinder getService(String name) {
        return getIServiceManager().getService(name); //如果cache中没有,就执行getIServiceManager().getService去获取
    }

    frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java

    public void onStart() {
        publishBinderService(Context.JOB_SCHEDULER_SERVICE, mJobSchedulerStub); //也就是说
                                               //ServiceManager.getService(JOB_SCHEDULER_SERVICE)拿到的其实是mJobSchedulerStub                                                                                                                                                                              //拿到的其实是mJobSchedulerStub
    }

    frameworks/base/services/core/java/com/android/server/SystemService.java

    protected final void publishBinderService(String name, IBinder service) {
        publishBinderService(name, service, false);
    }

    protected final void publishBinderService(String name, IBinder service,boolean allowIsolated) {
        ServiceManager.addService(name, service, allowIsolated);
    }

    frameworks/base/core/java/android/os/ServiceManager.java

    try {
        getIServiceManager().addService(name, service, allowIsolated);
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }

    1.3 mJobSchedulerStub schedule方法
    frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java

    final class JobSchedulerStub extends IJobScheduler.Stub {
        public int schedule(JobInfo job) throws RemoteException {
            return JobSchedulerService.this.schedule(job, uid);  //调用JobSchedulerService的方法
        }
    }

    public int schedule(JobInfo job, int uId) {
        JobStatus jobStatus = new JobStatus(job, uId); //JobInfo 被封装成JobStatus
        startTrackingJob(jobStatus);
    }

    private void startTrackingJob(JobStatus jobStatus) {
        update = mJobs.add(jobStatus);
    }
  2. 执行任务
    2.1 JobService里面的onStartJob方法怎么被触发
    frameworks/base/services/core/java/com/android/server/job/JobServiceContext.java

    public class JobServiceContext extends IJobCallback.Stub implements ServiceConnection {
        public void onServiceConnected(ComponentName name, IBinder service) {
            this.service = IJobService.Stub.asInterface(service); //说明这个service就是JobService.java里面所提供的远端Service
            mCallbackHandler.obtainMessage(MSG_SERVICE_BOUND).sendToTarget();
        }
    }

    private class JobServiceHandler extends Handler {
        public void handleMessage(Message message) {
            switch (message.what) {
                case MSG_SERVICE_BOUND:
                    handleServiceBoundH();
                    break;
            }
        }
        private void handleServiceBoundH() {
            service.startJob(mParams); //这里调用JobService.java里面的startJob
        }
    }
    

    frameworks/base/core/java/android/app/job/JobService.java

    IJobService mBinder = new IJobService.Stub() {   //IJobService.aidl的真正实现
        @Override
        public void startJob(JobParameters jobParams) {
            ensureHandler();
            Message m = Message.obtain(mHandler, MSG_EXECUTE_JOB, jobParams);
            m.sendToTarget();
        }
    
        @Override
        public void stopJob(JobParameters jobParams) {
              ensureHandler();
              Message m = Message.obtain(mHandler, MSG_STOP_JOB, jobParams);
              m.sendToTarget();
        }
    };

        

class JobHandler extends Handler {
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_EXECUTE_JOB:
                    try {
                        boolean workOngoing = JobService.this.onStartJob(params);
                        ackStartMessage(params, workOngoing);
                    } catch (Exception e) {
                        Log.e(TAG, "Error while executing job: " + params.getJobId());
                        throw new RuntimeException(e);
                    }
                    break;
              }
        }
    }

    public abstract boolean onStartJob(JobParameters params); //abstract留给子类去覆盖,执行真正的动作 

    
    2.2 JobServiceContext 作为ServiceConnection怎么被使用

    frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java

   public JobSchedulerService(Context context) {
        mControllers.add(ConnectivityController.get(this)); //JobSchedulerService初始化时创建ConnectivityController
    }

   
    frameworks/base/services/core/java/com/android/server/job/controllers/ConnectivityController.java

    public static ConnectivityController get(JobSchedulerService jms) {
        synchronized (sCreationLock) {
            if (mSingleton == null) {
               //创建ConnectivityController时会将参数JobSchedulerService作为mStateChangedListener而持有
               mSingleton = new ConnectivityController(jms, jms.getContext()); 
            }
            return mSingleton;
        }
    }

    frameworks/base/services/core/java/com/android/server/job/controllers/ConnectivityController.java

  public synchronized void onNetworkActive() { //网络可用时
        mStateChangedListener.onRunJobNow(js);
    }  

    frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java

    @Override
    public void onRunJobNow(JobStatus jobStatus) {
        mHandler.obtainMessage(MSG_JOB_EXPIRED, jobStatus).sendToTarget(); //JobHandler
    }
    private class JobHandler extends Handler {
        @Override
        public void handleMessage(Message message) {
            maybeRunPendingJobsH();
        }        

        private void maybeRunPendingJobsH() {
            availableContext.executeRunnableJob(nextPending) //availableContext为JobServiceContext       
        }            
    }   

    
    frameworks/base/services/core/java/com/android/server/job/JobServiceContext.java

   boolean executeRunnableJob(JobStatus job) {
        final Intent intent = new Intent().setComponent(job.getServiceComponent());//这里获得实现的JobService
        //这里进行bindService的动作,而ServiceConnection就是JobServiceContext,这样上层实现的JobService就与JobServiceContext建立了联系
        boolean binding = mContext.bindServiceAsUser(intent, this,Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND,new UserHandle(job.getUserId())); 
    }
    原文作者:Android源码分析
    原文地址: https://blog.csdn.net/lostfish123/article/details/54630977
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞