WorkMannager 是 安卓 jetpack 推出的一中方式 用于 处理一次性 长久性的 任务 而设计的。
WorkMannager 分配了 两种工作方式 OneTimeWorkRequest 和 .PeriodicWorkRequest 其中 OneTimeWorkRequest 这个是 执行 一次的任务调用 PeriodicWorkRequest 这个是定时执行 的调用 不论您选择以何种方式调度工作,请始终使用 WorkRequest。Worker 定义工作单元,WorkRequest(及其子类)则定义工作运行方式和时间。
设置调度加急
加急工作的特征
- 重要性:加急工作适用于对用户很重要或由用户启动的任务。
- 速度:加急工作最适合那些立即启动并在几分钟内完成的简短任务。
- 配额:限制前台执行时间的系统级配额决定了加急作业是否可以启动。
- 电源管理:电源管理限制(如省电模式和低电耗模式)不太可能影响加急工作。
- 延迟时间:系统立即执行加急工作,前提是系统的当前工作负载允许执行此操作。这意味着这些工作对延迟时间较为敏感,不能安排到以后执行。
其中最重要的是配额 接下来就说说配额
@SuppressLint("MissingGetterMatchingBuilder")
public @NonNull B setExpedited(@NonNull OutOfQuotaPolicy policy) {
mWorkSpec.expedited = true;
mWorkSpec.outOfQuotaPolicy = policy;
return getThis();
}
这是android 在 java 层的源码 可以看到 传入了一个 设置 超时的配额的选项 OutOfQuotaPolicy
这个 方法 把 当前 workRequest 设置为了重要 expedited = true 会告诉 workMananger 这个 工作是非常重要的 需要插个队 先执行 在这里有一个 特殊的类 就是 WorkSpec
WorkSpec
这个类是存储有关逻辑工作单元的信息。
@ColumnInfo(name = "id")
@PrimaryKey
@NonNull
public String id; // 对于 请求单元 的 UUID
@ColumnInfo(name = "state") // 对应 请求单元 的状态
@NonNull
public WorkInfo.State state = ENQUEUED;
@ColumnInfo(name = "worker_class_name")
@NonNull
public String workerClassName; // 对应请求单元的 work类名
@ColumnInfo(name = "input_merger_class_name")
public String inputMergerClassName;
@ColumnInfo(name = "input")
@NonNull
public Data input = Data.EMPTY;
@ColumnInfo(name = "output")
@NonNull
public Data output = Data.EMPTY;
@ColumnInfo(name = "initial_delay")
public long initialDelay;
@ColumnInfo(name = "interval_duration")
public long intervalDuration;
@ColumnInfo(name = "flex_duration")
public long flexDuration;
@Embedded
@NonNull
public Constraints constraints = Constraints.NONE; // 对应请求单元 的其他信息
@ColumnInfo(name = "run_attempt_count")
@IntRange(from = 0)
public int runAttemptCount;
@ColumnInfo(name = "backoff_policy")
@NonNull
public BackoffPolicy backoffPolicy = BackoffPolicy.EXPONENTIAL;
@ColumnInfo(name = "backoff_delay_duration")
public long backoffDelayDuration = WorkRequest.DEFAULT_BACKOFF_DELAY_MILLIS;
/**
* For one-off work, this is the time that the work was unblocked by prerequisites.
* For periodic work, this is the time that the period started.
*/
@ColumnInfo(name = "period_start_time")
public long periodStartTime; // 对应请求单元的延迟时间
@ColumnInfo(name = "minimum_retention_duration")
public long minimumRetentionDuration;
其中最重要的是
public OutOfQuotaPolicy outOfQuotaPolicy = OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST;
这行代码 说明 workMannager 设置的默认的 配额超出 处理方式是 OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST
表示 当应用程序没有任何加急工作配额时,加急工作请求将回退到常规工作请求
这个它还提供了通过外部用户自定义 WorkSpec的构造方式
public WorkSpec(@NonNull WorkSpec other) {
id = other.id;
workerClassName = other.workerClassName;
state = other.state;
inputMergerClassName = other.inputMergerClassName;
input = new Data(other.input);
output = new Data(other.output);
initialDelay = other.initialDelay;
intervalDuration = other.intervalDuration;
flexDuration = other.flexDuration;
constraints = new Constraints(other.constraints);
runAttemptCount = other.runAttemptCount;
backoffPolicy = other.backoffPolicy;
backoffDelayDuration = other.backoffDelayDuration;
periodStartTime = other.periodStartTime;
minimumRetentionDuration = other.minimumRetentionDuration;
scheduleRequestedAt = other.scheduleRequestedAt;
expedited = other.expedited;
outOfQuotaPolicy = other.outOfQuotaPolicy;
}