性能优化(8.5)-JobScheduler的源码分析
.JobSchedulerService
因为实例化一个JobSchedulerService类的时候,会执行构造函数的代码:
public final class JobSchedulerService extends com.android.server.SystemService
implements StateChangedListener, JobCompletedListener {
final JobHandler mHandler;//主要处理任务到期,任务检查,任务结束等消息
final Constants mConstants;//存放一些常量
final JobSchedulerStub mJobSchedulerStub;//Binder接口的代理类
final JobStore mJobs;//里面维护了一个Job集合,从data/system/job/jobs.xml文件中读取的永久性任务
List mControllers;//控制器集合
…
public JobSchedulerService(Context context) {
super(context);
//初始化
mHandler = new JobHandler(context.getMainLooper());
mConstants = new Constants(mHandler);
mJobSchedulerStub = new JobSchedulerStub();
mJobs = JobStore.initAndGet(this);
// Create the controllers.
mControllers = new ArrayList<StateController>();
//网络连接情况控制器
mControllers.add(ConnectivityController.get(this));
//执行时机控制器
mControllers.add(TimeController.get(this));
//空闲状态控制器
mControllers.add(IdleController.get(this));
//电量情况控制器
mControllers.add(BatteryController.get(this));
//应用空闲状态控制器
mControllers.add(AppIdleController.get(this));
//URIs内容变化控制器
mControllers.add(ContentObserverController.get(this));
//设备空闲状态控制器
mControllers.add(DeviceIdleJobsController.get(this));
}
…
}
我们首先看到JobSchedulerService类实现了StateChangedListener接口,然后我们看到所有的控制器都是实现的StateController类。首先来看看这个接口和类:
public interface StateChangedListener {
//控制器调用这个方法来通知JobManager 该检查一个任务的状态了,因为这里JobSchedulerService
//实现了这个接口,所以会调用JobSchedulerService里面这个方法的实现
public void onControllerStateChanged();
//控制器调用这个方法通知JobManager ,应该马上执行任务了
public void onRunJobNow(JobStatus jobStatus);
//设备的空闲状态发生改变调用这个方法
public void onDeviceIdleStateChanged(boolean deviceIdle);
}
我们知道JobSchedulerService 实现了这个接口,所以调用这里的接口就会调用到JobSchedulerService 中的方法实现。
public abstract class StateController {
protected static final boolean DEBUG = JobSchedulerService.DEBUG;
protected final Context mContext;
protected final Object mLock;
protected final StateChangedListener mStateChangedListener;
public StateController(StateChangedListener stateChangedListener, Context context,
Object lock) {
mStateChangedListener = stateChangedListener;
mContext = context;
mLock = lock;
}
//添加需要监听的任务,同时在任务更新的时候也会调用
public abstract void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob);
//可选实现,在任务执行前做准备
public void prepareForExecutionLocked(JobStatus jobStatus) {
}
//清除该任务,当任务被取消,或者完成的时候调用
public abstract void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
boolean forUpdate);
//当一个新任务被创建来重新执行之前失败的任务时调用
public void rescheduleForFailure(JobStatus newJob, JobStatus failureToReschedule) {
}
public abstract void dumpControllerStateLocked(PrintWriter pw, int filterUid);
}
我们看到所有的控制器都是继承的这个抽象类,而且实现了里面的几个抽象方法。这里我们就挑一个控制器来看看实现,这里我们选择ConnectivityController控制器来看下流程。
2.ConnectivityController
public class ConnectivityController extends StateController implements
ConnectivityManager.OnNetworkActiveListener {
private static final String TAG = "JobScheduler.Conn";
//网络连接管理类,用于获取活跃网络信息
private final ConnectivityManager mConnManager;
//提供网络策略管理服务
private final NetworkPolicyManager mNetPolicyManager;
//追踪的任务的列表
@GuardedBy("mLock")
private final ArrayList<JobStatus> mTrackedJobs = new ArrayList<JobStatus>();
/** Singleton. */
private static ConnectivityController mSingleton;
private static Object sCreationLock = new Object();
//获取控制类实例:单例
public static ConnectivityController get(JobSchedulerService jms) {
synchronized (sCreationLock) {
if (mSingleton == null) {
mSingleton = new ConnectivityController(jms, jms.getContext(), jms.getLock());
}
return mSingleton;
}
}
private ConnectivityController(StateChangedListener stateChangedListener, Context context,
Object lock) {
super(stateChangedListener, context, lock);
//获取管理类实例
mConnManager = mContext.getSystemService(ConnectivityManager.class);
mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
//注册网络广播
final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiverAsUser(
mConnectivityReceiver, UserHandle.SYSTEM, intentFilter, null, null);
mNetPolicyManager.registerListener(mNetPolicyListener);
}
@Override
public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
//判断是否有连接约束,是否有不按用量计费的约束,是否有不允许漫游的约束
//(这些可以通过JobInfo的builder方法设置)
if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()
|| jobStatus.hasNotRoamingConstraint()) {
//更新任务的约束
updateConstraintsSatisfied(jobStatus);
//将任务添加进追踪列表
mTrackedJobs.add(jobStatus);
}
}
@Override
public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
boolean forUpdate) {
if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()
|| jobStatus.hasNotRoamingConstraint()) {
//从追踪列表中删除任务
mTrackedJobs.remove(jobStatus);
}
}
private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
final boolean ignoreBlocked = (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
//获取活跃网络的信息
final NetworkInfo info = mConnManager.getActiveNetworkInfoForUid(jobStatus.getSourceUid(),
ignoreBlocked);
final boolean connected = (info != null) && info.isConnected();
final boolean unmetered = connected && !info.isMetered();
final boolean notRoaming = connected && !info.isRoaming();
boolean changed = false;
//更新任务的网络相关标识
changed |= jobStatus.setConnectivityConstraintSatisfied(connected);
changed |= jobStatus.setUnmeteredConstraintSatisfied(unmetered);
changed |= jobStatus.setNotRoamingConstraintSatisfied(notRoaming);
return changed;
}
/**
* Update all jobs tracked by this controller.
*
* @param uid only update jobs belonging to this UID, or {@code -1} to
* update all tracked jobs.
*/
private void updateTrackedJobs(int uid) {
synchronized (mLock) {
boolean changed = false;
//遍历任务追踪列表
for (int i = 0; i < mTrackedJobs.size(); i++) {
final JobStatus js = mTrackedJobs.get(i);
if (uid == -1 || uid == js.getSourceUid()) {
//更新约束
changed |= updateConstraintsSatisfied(js);
}
}
// 如果changed为true,则调用监听器(即JobSchedulerService)的onControllerStateChanged方法
if (changed) {
mStateChangedListener.onControllerStateChanged();
}
}
}
/**
* We know the network has just come up. We want to run any jobs that are ready.
*/
@Override
public synchronized void onNetworkActive() {
synchronized (mLock) {
for (int i = 0; i < mTrackedJobs.size(); i++) {
final JobStatus js = mTrackedJobs.get(i);
if (js.isReady()) {
if (DEBUG) {
Slog.d(TAG, "Running " + js + " due to network activity.");
}
//当网络状态良好,我们就可以遍历追踪列表取出任务,然后调用下面方法马上执行
mStateChangedListener.onRunJobNow(js);
}
}
}
}
private BroadcastReceiver mConnectivityReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//接收到网络广播则更新追踪的任务
updateTrackedJobs(-1);
}
};
private INetworkPolicyListener mNetPolicyListener = new INetworkPolicyListener.Stub() {
//网络策略变化则回调这里的相应方法
@Override
public void onUidRulesChanged(int uid, int uidRules) {
updateTrackedJobs(uid);
}
日记本
相关推荐
阿里Andorid研发一面:小姑娘挺不错来给我先讲讲Fragment和Activity相关吧
阅读 1764
免费报名>>中欧MBA公开课
广告
开心一刻
阅读 4618
中国人为什么不吃猫肉?原来李时珍早就已告诉我们答案,古人试过
阅读 2826
2019 Android中级面试题集(小厂篇)
阅读 650