mJobScheduler=(JobScheduler)getSystemService(Context.JOB_SCHEDULER_SERVICE);
mJobInfo=new JobInfo.Builder(i,mComponentName).setMinimumLatency(5*1000).build();
mJobScheduler.schedule(mJobInfo);
上图提到,我们可以从zygote进程孵化一个新的系统服务进程,也叫做SystemServer。这里我们可以先找到main函数,看下他是如何创建一系列的系统子服务的:
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
//启动服务
try {
startBootstrapServices();
startCoreServices();
startOtherServices();//启动系统级服务
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
}
private void startOtherServices() {
mSystemServiceManager.startService(JobSchedulerService.class);
}
上一节我们看到JobSchedulerService远程服务已经被启动了,如何启动呢,实际上是通过反射JobSchedulerService该类并调用该类的构造器初始化的:
public T startService(Class serviceClass) {
final String name = serviceClass.getName();
final T service;
try {
Constructor cOnstructor= serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
}
mServices.add(service);
return service;
}
接下来我们看看他们是如何初始化:
public class JobSchedulerService extends com.android.server.SystemService
implements StateChangedListener, JobCompletedListener {
public JobSchedulerService(Context context) {
super(context);
// 初始化所有的控制器(每个JobInfo都会创建一系列的约束,必须免费的网络,系统空闲,时间 电量约束等等)
mCOntrollers= new ArrayList();
mControllers.add(ConnectivityController.get(this));
mControllers.add(TimeController.get(this));
mControllers.add(IdleController.get(this));
mControllers.add(BatteryController.get(this));
//操作任务逻辑的处理器
mHandler = new JobHandler(context.getMainLooper());
//远程服务的代理对象 很重要 至此!!!进程一服务端我们已经分析完毕
mJobSchedulerStub = new JobSchedulerStub();
// 读取任务进度的持久化文件 /system/job/jobs.xml
mJobs = JobStore.initAndGet(this);
}
}
还记得我们调用代码的顺序吗,当我们获取服务后,我们会调用如下代码:
mJobScheduler.schedule(mJobInfo);
此刻通过进程二服务端的图你会发现,JobScheduer是一个抽象类,而它还有一个子类实现。当我们调用schedule方法的时候,子类通过代理调用了服务端的schedule():
public abstract class JobScheduler {}
public class JobSchedulerImpl extends JobScheduler {
IJobScheduler mBinder;
/* package */ JobSchedulerImpl(IJobScheduler binder) {
mBinder = binder;
}
@Override
public int schedule(JobInfo job) {
try {
return mBinder.schedule(job);
} catch (RemoteException e) {
return JobScheduler.RESULT_FAILURE;
}
}
...
}
回到进程一服务端查看JobSchedulerStub代理是如何处理的:
@Override
public int schedule(JobInfo job) throws RemoteException {
...
try {
//调用JobSchedulerService的schedule(job, uid)
return JobSchedulerService.this.schedule(job, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
public class JobSchedulerService{
public int schedule(JobInfo job, int uId) {
//1.封装任务为JobStatus
JobStatus jobStatus = new JobStatus(job, uId);
//2.如果之前任务已经存在 替换
cancelJob(uId, job.getId());
//3.开始跟踪任务 我们之前说过 JobInfo会携带各种约束,这里根据各种约束开始跟踪任务,会调用到约束的maybeStartTrackingJob()。
startTrackingJob(jobStatus);
//4.检查是否需要马上执行任务。
mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
return JobScheduler.RESULT_SUCCESS;
}
}
之前我们提到,在创建JobInfo必须设置约束才可以。那么服务端也创建了一些列控制器来跟踪任务的状态。这个我们在JobScheduler创建的时候已经提过了。他们有个共同的父类StateController。
public abstract class StateController {
//开始跟踪任务
public abstract void maybeStartTrackingJob(JobStatus jobStatus);
//结束跟踪任务
public abstract void maybeStopTrackingJob(JobStatus jobStatus);
public abstract void dumpControllerState(PrintWriter pw);
}
以第一个子类ConnectivityController为例他是通过get静态方式初始化的:
public class ConnectivityController extends StateController implements
ConnectivityManager.OnNetworkActiveListener {
public static ConnectivityController get(JobSchedulerService jms) {
synchronized (sCreationLock) {
if (mSingleton == null) {
mSingleton = new ConnectivityController(jms, jms.getContext());
}
return mSingleton;
}
}
private ConnectivityController(StateChangedListener stateChangedListener, Context context) {
super(stateChangedListener, context);
// Register connectivity changed BR.
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiverAsUser(
mConnectivityChangedReceiver, UserHandle.ALL, intentFilter, null, null);
ConnectivityService cs =
(ConnectivityService)ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (cs != null) {
if (cs.getActiveNetworkInfo() != null) {
mNetworkCOnnected= cs.getActiveNetworkInfo().isConnected();
}
mNetworkUnmetered = mNetworkConnected && !cs.isActiveNetworkMetered();
}
}
}
上面的代码完成了如下几件事:
注册了一个叫做ConnectivityChangedReceiver广播接收者。当网络改变的时候就会调用该方法。
class ConnectivityChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
//获取网络的类型...
if (activeNetwork == null) {
...
updateTrackedJobs(userid);
} else if (activeNetwork.getType() == networkType) {
...
updateTrackedJobs(userid);
}
}
}
};
private void updateTrackedJobs(int userId) {
synchronized (mTrackedJobs) {
//... 如果网络改变了 则通过监听器告诉JobSchedulerService
if (changed) {
mStateChangedListener.onControllerStateChanged();
}
}
}
我们看下当某个条件触发。JobSchedulerService是如何处理的:
@Override
public void onControllerStateChanged() {
mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
}
private class JobHandler extends Handler {
...
@Override
public void handleMessage(Message message) {
...
switch (message.what) {
case MSG_JOB_EXPIRED:
synchronized (mJobs) {
JobStatus runNow = (JobStatus) message.obj;
...
if (runNow != null && !mPendingJobs.contains(runNow)
&& mJobs.containsJob(runNow)) {
mPendingJobs.add(runNow);
}
queueReadyJobsForExecutionLockedH();
}
break;
case MSG_CHECK_JOB:
...
maybeQueueReadyJobsForExecutionLockedH();
break;
}
maybeRunPendingJobsH();
removeMessages(MSG_CHECK_JOB);
}
}
上面的代码主要执行三个有效的方法:
maybeRunPendingJobsH()是如何关联我们熟悉的JobService的?
private void maybeRunPendingJobsH() {
synchronized (mJobs) {
Iterator it = mPendingJobs.iterator();
while (it.hasNext()) {
//1.拿到等待执行的任务
JobStatus nextPending = it.next();
...
//2.从执行列表中移除当前任务
if (!availableContext.executeRunnableJob(nextPending)) {
if (DEBUG) {
Slog.d(TAG, "Error executing " + nextPending);
}
//3.从待运行的列表中移除
mJobs.remove(nextPending);
}
it.remove();
}
}
}
JobServiceContext是如何执行executeRunnableJob(nextPending)去执行任务的,代码如下:
boolean executeRunnableJob(JobStatus job) {
//构建任务参数
mParams = new JobParameters(this, job.getJobId(), job.getExtras(),
!job.isConstraintsSatisfied());
//绑定我们当初在JobInfo中传入的服务对象。
boolean binding = mContext.bindServiceAsUser(intent, this,
Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND,
new UserHandle(job.getUserId()));
}
绑定JobService服务后,实现了如下:
onBind()被调用,返回代理对象
public abstract class JobService extends Service {
IJobService mBinder = new IJobService.Stub() {
@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();
}
};
public final IBinder onBind(Intent intent) {
return mBinder.asBinder();
}
}
JobServiceContext的onServiceConnected()被调用:
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//内部wake_lock锁在这里。。。
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();
}
private class JobServiceHandler extends Handler {
@Override
public void handleMessage(Message message) {
//case MSG_SERVICE_BOUND:
handleServiceBoundH();
}
private void handleServiceBoundH() {
...
//最最最...终启动了onStartJob();
service.startJob(mParams);
}
}