JobSchedulerService 源码分析—— BatteryController (API 21)

设置了电量约束条件的 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();
    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
    }
}

你可能感兴趣的:(JobSchedulerService 源码分析—— BatteryController (API 21))