了解 WorkManager 的 WorkSpec table
Understand WorkManager's WorkSpec table
我一直在我的应用程序中使用 workManager。我已经看到它使用 table 之一创建了一个名为 workSpec 的数据库。我有所有的工人信息都存储在里面。我想了解 table 的列,例如状态、运行 尝试计数、period_start_time 等
注意:
- WorkManager 版本:1.0.1
- 设备始终连接到充电电源,因此没有机会
打瞌睡。
我还有其他问题:
- 如何减小数据库的大小,因为我看到它正在疯狂增长并且没有删除旧的未使用的项目。
- 在图中显示的同一个工人中,它被安排为每 1 小时 运行 的周期性请求,但它只有一次 运行 并且再也没有来过。为什么?
定期请求代码
public WorkRequest createWorkRequest(int interval, String tagName) {
if (tagName.endsWith(Task.TAG_SUFFIX)) {
return new PeriodicWorkRequest.Builder(CommonWorker.class, interval, TimeUnit.SECONDS)
.addTag(tagName)
.build();
}
return new OneTimeWorkRequest.Builder(CommonWorker.class)
.setInitialDelay(interval, TimeUnit.SECONDS)
.addTag(tagName)
.build();
}
和
private void triggerSchedulerFor(int interval, String tagName) {
WorkRequest workRequest = zdsWorkRequest.createWorkRequest(interval, tagName);
Operation operation;
if (tagName.endsWith(Task.TAG_SUFFIX)) {
operation = workManager.enqueueUniquePeriodicWork(tagName,
ExistingPeriodicWorkPolicy.REPLACE,
(PeriodicWorkRequest) workRequest);
} else {
operation = workManager.enqueueUniqueWork(tagName, ExistingWorkPolicy.REPLACE,
(OneTimeWorkRequest) workRequest);
}
Log.i(TAG, "State for Tag = " + tagName + " is = " + operation.getState().getValue());
}
- 有另一个工人必须定期 运行 每 15 分钟一次,但我看到了一种模式,它恰好每 15 分钟触发一次,但每 1 小时后,15 分钟的工人触发,延迟 11 分钟,即下面是日志跟踪
Line 2614: 05-30 09:41:28.876 17609 17609 I TaskPlannerImpl:
onTaskTimerElapsed 900_SEC Line 6359: 05-30 09:56:28.907 17609 17609
I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 9081: 05-30
10:11:52.355 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC
Line 12991: 05-30 10:26:28.901 17609 17609 I TaskPlannerImpl:
onTaskTimerElapsed 900_SEC Line 17115: 05-30 10:50:03.389 17609 17609
I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 18727: 05-30
10:56:28.881 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC
Line 20945: 05-30 11:11:28.907 17609 17609 I TaskPlannerImpl:
onTaskTimerElapsed 900_SEC Line 23068: 05-30 11:26:28.909 17609 17609
I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 26932: 05-30
11:52:40.685 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC
Line 27598: 05-30 11:56:28.903 17609 17609 I TaskPlannerImpl:
onTaskTimerElapsed 900_SEC Line 29724: 05-30 12:11:28.896 17609 17609
I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 31790: 05-30
12:26:28.902 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC
Line 34414: 05-30 12:46:14.844 17609 17609 I TaskPlannerImpl:
onTaskTimerElapsed 900_SEC Line 36131: 05-30 12:56:28.902 17609 17609
I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 38692: 05-30
13:11:28.881 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC
Line 41469: 05-30 13:26:28.902 17609 17609 I TaskPlannerImpl:
onTaskTimerElapsed 900_SEC
关于 workSpec table 格式,这显然是将来可能会更改的实现细节。我会避免直接对其进行任何更改或假设某些特定信息以特定格式存储。
可以从WorkSpec
source. Some of these information are accessible through WorkManager's API. As an example, you can access the attempt count both inside your Worker (ListenableWorker#getRunAttemptCount()
) and through WorkInfo
(WorkManager v2.1.0-alpha01 added `WorkInfo#getRunAttemptCount()'.
中看到它当前存储的内容
但同样,您永远不应直接对 WorkManager 的 table 进行任何更改或依赖其特定格式。
关于您的其他问题:
减少 WorkManager 的数据库大小
创建 WorkRequest 时,您可以使用 keepResultsForAtLeast()
指定需要将此 workRequest 在数据库中保留多长时间。请记住,一旦从数据库中删除了 WorkRequest,您就无法获得有关它的更多信息。
另一个更激烈和危险的选择是使用 WorkManager#pruneWork()
。在这种情况下,WorkManager 从数据库中删除所有已完成的工作。同样,在此操作之后,将无法再访问 WorkRequest 的 WorkInfo
.
PeriodicWorker 不重复
了解您如何创建 WorkRequest 和 Worker 代码会很有用,device/OS 您是否看到过这种行为以及您使用的是哪个 WorkManager 版本。
PeriodicWorker 的非精确间隔
WorkManager 尝试遵守与 Android OS 电池优化策略(主要是打盹模式)兼容的 WorkRequest 参数。这可能会导致 Worker 被转移到最近的 maintenance window.
我一直在我的应用程序中使用 workManager。我已经看到它使用 table 之一创建了一个名为 workSpec 的数据库。我有所有的工人信息都存储在里面。我想了解 table 的列,例如状态、运行 尝试计数、period_start_time 等
注意:
- WorkManager 版本:1.0.1
- 设备始终连接到充电电源,因此没有机会 打瞌睡。
我还有其他问题:
- 如何减小数据库的大小,因为我看到它正在疯狂增长并且没有删除旧的未使用的项目。
- 在图中显示的同一个工人中,它被安排为每 1 小时 运行 的周期性请求,但它只有一次 运行 并且再也没有来过。为什么?
定期请求代码
public WorkRequest createWorkRequest(int interval, String tagName) {
if (tagName.endsWith(Task.TAG_SUFFIX)) {
return new PeriodicWorkRequest.Builder(CommonWorker.class, interval, TimeUnit.SECONDS)
.addTag(tagName)
.build();
}
return new OneTimeWorkRequest.Builder(CommonWorker.class)
.setInitialDelay(interval, TimeUnit.SECONDS)
.addTag(tagName)
.build();
}
和
private void triggerSchedulerFor(int interval, String tagName) {
WorkRequest workRequest = zdsWorkRequest.createWorkRequest(interval, tagName);
Operation operation;
if (tagName.endsWith(Task.TAG_SUFFIX)) {
operation = workManager.enqueueUniquePeriodicWork(tagName,
ExistingPeriodicWorkPolicy.REPLACE,
(PeriodicWorkRequest) workRequest);
} else {
operation = workManager.enqueueUniqueWork(tagName, ExistingWorkPolicy.REPLACE,
(OneTimeWorkRequest) workRequest);
}
Log.i(TAG, "State for Tag = " + tagName + " is = " + operation.getState().getValue());
}
- 有另一个工人必须定期 运行 每 15 分钟一次,但我看到了一种模式,它恰好每 15 分钟触发一次,但每 1 小时后,15 分钟的工人触发,延迟 11 分钟,即下面是日志跟踪
Line 2614: 05-30 09:41:28.876 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 6359: 05-30 09:56:28.907 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 9081: 05-30 10:11:52.355 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 12991: 05-30 10:26:28.901 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 17115: 05-30 10:50:03.389 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 18727: 05-30 10:56:28.881 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 20945: 05-30 11:11:28.907 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 23068: 05-30 11:26:28.909 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 26932: 05-30 11:52:40.685 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 27598: 05-30 11:56:28.903 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 29724: 05-30 12:11:28.896 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 31790: 05-30 12:26:28.902 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 34414: 05-30 12:46:14.844 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 36131: 05-30 12:56:28.902 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 38692: 05-30 13:11:28.881 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC Line 41469: 05-30 13:26:28.902 17609 17609 I TaskPlannerImpl: onTaskTimerElapsed 900_SEC
关于 workSpec table 格式,这显然是将来可能会更改的实现细节。我会避免直接对其进行任何更改或假设某些特定信息以特定格式存储。
可以从WorkSpec
source. Some of these information are accessible through WorkManager's API. As an example, you can access the attempt count both inside your Worker (ListenableWorker#getRunAttemptCount()
) and through WorkInfo
(WorkManager v2.1.0-alpha01 added `WorkInfo#getRunAttemptCount()'.
但同样,您永远不应直接对 WorkManager 的 table 进行任何更改或依赖其特定格式。
关于您的其他问题:
减少 WorkManager 的数据库大小
创建 WorkRequest 时,您可以使用 keepResultsForAtLeast()
指定需要将此 workRequest 在数据库中保留多长时间。请记住,一旦从数据库中删除了 WorkRequest,您就无法获得有关它的更多信息。
另一个更激烈和危险的选择是使用 WorkManager#pruneWork()
。在这种情况下,WorkManager 从数据库中删除所有已完成的工作。同样,在此操作之后,将无法再访问 WorkRequest 的 WorkInfo
.
PeriodicWorker 不重复
了解您如何创建 WorkRequest 和 Worker 代码会很有用,device/OS 您是否看到过这种行为以及您使用的是哪个 WorkManager 版本。
PeriodicWorker 的非精确间隔
WorkManager 尝试遵守与 Android OS 电池优化策略(主要是打盹模式)兼容的 WorkRequest 参数。这可能会导致 Worker 被转移到最近的 maintenance window.