Ara*_*ram 9 android android-architecture-components android-jetpack android-workmanager
我们正在使用OneTimeWorkRequest在我们的项目中启动后台任务.
在某些情况下,如果应用程序在工作请求A正在进行时被杀死,Android会在应用程序重新启动时自动重新启动请求A. 我们再次再次启动请求A. 因此,请求A的两个实例并行运行并导致死锁.
为了避免这种情况,我在app start中执行了以下代码来检查worker是否正在运行但是这总是返回false.
public static boolean isMyWorkerRunning(String tag) {
List<WorkStatus> status = WorkManager.getInstance().getStatusesByTag(tag).getValue();
return status != null;
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来处理这个?
我检查了beginUniqueWork().如果我只有一个请求,是否更昂贵?
编辑2: 这个问题是关于独特的一次性任务.为了启动唯一的Periodic任务,我们有一个单独的API enqueueUniquePeriodicWork().但是我们没有用于启动独特的一次性工作的API.我很困惑在继续对象之间使用或手动检查和启动方法.
在最近的构建中,他们为这个enqueueUniqueWork()添加了新的api.这是他们在发行说明中提到的确切原因.
添加WorkManager.enqueueUniqueWork()API以将唯一的OneTimeWorkRequests排入队列,而无需创建WorkContinuation. https://developer.android.com/jetpack/docs/release-notes
您可以使用beginUniqueWork()
唯一的名称。
如果您使用ExistingWorkPolicy :
APPEND: 2 个请求将串行运行。
KEEP:如果第一个请求正在运行,则不会运行第二个请求。
REPLACE:2 个请求将并行运行。
编辑2:
11月8日发行说明:
https://developer.android.com/jetpack/docs/release-notes
添加WorkManager.enqueueUniqueWork()API以使唯一的OneTimeWorkRequest入队,而无需创建WorkContinuation。
这就是说,alpha11拥有这个新的API来唯一地排队一次工作。
我尝试如下更改代码:
OneTimeWorkRequest impWork = new OneTimeWorkRequest.Builder(WorkerNotesAttachment.class)
.addTag(RWORK_TAG_NOTES)
.build();
WorkManager.getInstance().enqueueUniqueWork(RWORK_TAG_NOTES, ExistingWorkPolicy.REPLACE, impWork);
Run Code Online (Sandbox Code Playgroud)
我尝试使用beginUniqueWork API。但是有时无法运行。因此,我最终编写了以下函数。
public static boolean isMyWorkerRunning(String tag) {
List<WorkStatus> status = null;
try {
status = WorkManager.getInstance().getStatusesByTag(tag).get();
boolean running = false;
for (WorkStatus workStatus : status) {
if (workStatus.getState() == State.RUNNING
|| workStatus.getState() == State.ENQUEUED) {
return true;
}
}
return false;
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我们需要获取所有WorkStatus对象,并检查其中至少一个处于“运行”或“入队”状态。由于系统将所有已完成的工作保留在数据库中几天(请参阅pruneWork()),因此我们需要检查所有工作实例。
在启动OneTimeWorkRequest之前,请调用此函数。
public static void startCacheWorker() {
String tag = RWORK_TAG_CACHE;
if (isMyWorkerRunning(tag)) {
log("worker", "RWORK: tag already scheduled, skipping " + tag);
return;
}
// Import contact for given network
OneTimeWorkRequest impWork = new OneTimeWorkRequest.Builder(WorkerCache.class)
.addTag(tag)
.build();
WorkManager.getInstance().enqueue(impWork);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4397 次 |
最近记录: |