设置了电量约束条件的 Job 执行一次后不会被移除
/** Wait this long after phone is plugged in before doing any work. */
private static final long STABLE_CHARGING_THRESHOLD_MILLIS = 2 * 60 * 1000; // 2 minutes.
一、调用流程
public JobSchedulerService(Context context) {
super(context);
// 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));
mHandler = new JobSchedulerService.JobHandler(context.getMainLooper());
mJobSchedulerStub = new JobSchedulerService.JobSchedulerStub();
mJobs = JobStore.initAndGet(this);
}
|
public static BatteryController get(JobSchedulerService taskManagerService) {
synchronized (sCreationLock) {
if (sController == null) {
sController = new BatteryController(taskManagerService, taskManagerService.getContext());
}
}
return sController;
}
|
private BatteryController(StateChangedListener stateChangedListener, Context context) {
super(stateChangedListener, context);
mChargeTracker = new ChargingTracker();
// 注册广播接收器,初始化当前电量状态
mChargeTracker.startTracking();
}
二、初始化 ChargingTracker
public ChargingTracker() {
mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(ACTION_CHARGING_STABLE);
mStableChargingTriggerIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
}
注册广播接收器,初始化当前电量状态
public void startTracking() {
IntentFilter filter = new IntentFilter();
// Battery health.
filter.addAction(Intent.ACTION_BATTERY_LOW);
filter.addAction(Intent.ACTION_BATTERY_OKAY);
// Charging/not charging.
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
// Charging stable.
filter.addAction(ACTION_CHARGING_STABLE);
mContext.registerReceiver(this, filter);
// Initialise tracker state.
BatteryManagerInternal batteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class);
mBatteryHealthy = !batteryManagerInternal.getBatteryLevelLow();
mCharging = batteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
}
三、添加需要追踪的 Job
public void maybeStartTrackingJob(JobStatus taskStatus) {
// 判断当前是否"正在充电并且电量健康"
final boolean isOnStablePower = mChargeTracker.isOnStablePower();
if (taskStatus.hasChargingConstraint()) {
synchronized (mTrackedTasks) {
mTrackedTasks.add(taskStatus);
taskStatus.chargingConstraintSatisfied.set(isOnStablePower);
}
}
if (isOnStablePower) {
// 设置 AlarmManager 触发时间,2min 后触发
mChargeTracker.setStableChargingAlarm();
}
}
四、移除不再需要追踪的 Job
public void maybeStopTrackingJob(JobStatus taskStatus) {
if (taskStatus.hasChargingConstraint()) {
synchronized (mTrackedTasks) {
mTrackedTasks.remove(taskStatus);
}
}
}
五、通过 Receiver 驱动 Job 执行的流程
public void onReceive(Context context, Intent intent) {
onReceiveInternal(intent);
}
|
public void onReceiveInternal(Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_BATTERY_LOW.equals(action)) {
// Battery life too low to do work
// If we get this action, the battery is discharging => it isn't plugged in so
// there's no work to cancel. We track this variable for the case where it is
// charging, but hasn't been for long enough to be healthy.
mBatteryHealthy = false;
} else if (Intent.ACTION_BATTERY_OKAY.equals(action)) {
// Indicates the battery is now okay after being low, 由低电量状态转换为非低电量状态
// Battery life healthy enough to do work
mBatteryHealthy = true;
// 触发该 controller 的检查
maybeReportNewChargingState();
} else if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
// Set up an alarm for ACTION_CHARGING_STABLE - we don't want to kick off tasks
// here if the user unplugs the phone immediately.
// 设置 AlarmManager 触发时间,2min 后触发
setStableChargingAlarm();
mCharging = true;
} else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
// If an alarm is set, breathe a sigh of relief and cancel it - crisis averted.
mAlarm.cancel(mStableChargingTriggerIntent);
mCharging = false;
// 触发该 controller 的检查
maybeReportNewChargingState();
}else if (ACTION_CHARGING_STABLE.equals(action)) {
// Here's where we actually do the notify for a task being ready.
// 进入充电状态两分钟后触发,或者充电时有新 Job 加入的两分钟后触发
if (mCharging) { // Should never receive this intent if mCharging is false.
// 触发该 controller 的检查
maybeReportNewChargingState();
}
}
}
BatteryController 检测达到电量约束条件后不会移除 Job
private void maybeReportNewChargingState() {
final boolean stablePower = mChargeTracker.isOnStablePower();
boolean reportChange = false;
synchronized (mTrackedTasks) {
for (JobStatus ts : mTrackedTasks) {
boolean previous = ts.chargingConstraintSatisfied.getAndSet(stablePower);
if (previous != stablePower) { // 有 Job 的电量约束条件发生了变化,随后触发 JobSchedulerService 进行检查
reportChange = true;
}
}
}
// Let the scheduler know that state has changed. This may or may not result in an execution.
// 触发 JobSchedulerService 检查所有满足执行条件的 Job,根据策略决定是否放入 mPendingJobs,随后执行 mPendingJobs 中的 Job
if (reportChange) {
mStateChangedListener.onControllerStateChanged();
}
// Also tell the scheduler that any ready jobs should be flushed.
// 电量状态健康,触发 JobSchedulerService 检查所有满足执行条件的 Job,放入 mPendingJobs,随后执行
if (stablePower) {
mStateChangedListener.onRunJobNow(null); // 注意此处传 null
}
}