您的位置:首页 > 移动开发 > Android开发

Android系统分析之JobScheduler源码分析

2016-12-11 22:02 483 查看

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);//要求给定应用程序服务启动
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 源码