功耗之使用job任务

性能优化(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

发布了81 篇原创文章 · 获赞 0 · 访问量 1309

猜你喜欢

转载自blog.csdn.net/qq_42894864/article/details/104044765