放入任务
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.javapublic 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.javafinal 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.1 JobService里面的onStartJob方法怎么被触发
frameworks/base/services/core/java/com/android/server/job/JobServiceContext.javapublic 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()));
}