Hec*_*tor 5 android android-workmanager
我当前的 Android 应用程序采用
archWorkerRuntimeVersion = '2.3.0-beta02'
api "androidx.work:work-runtime:$archWorkerRuntimeVersion"
api "androidx.work:work-runtime-ktx:$archWorkerRuntimeVersion"
Run Code Online (Sandbox Code Playgroud)
处理后台工作。
当工作人员运行时,我会显示一个工具栏进度旋转器,向用户发出该应用程序“忙”的信号。
我的应用程序由多个活动组成,我使用 Android JetPack ViewModels 来管理 Worker。
我开始工作如下:-
val myWorkRequest: OneTimeWorkRequest =
OneTimeWorkRequest.Builder(MyWorker::class.java)
.addTag(WORK_IN_PROGRESS_TAG + "${UUID.randomUUID()}").build()
WorkManager.getInstance(applicationContext)
.beginUniqueWork(
UNIQUE_WORK_NAME,
ExistingWorkPolicy.KEEP,
myWorkRequest
)
.enqueue()
Run Code Online (Sandbox Code Playgroud)
我有一个观察者定义如下:-
private val observer = Observer<WorkInfo> { workInfo ->
when(workInfo.state) {
WorkInfo.State.RUNNING -> Log.e("OBSERVING", "${UUID.randomUUID()} :: show Progress Spinner")
WorkInfo.State.ENQUEUED -> Log.e("OBSERVING", "${UUID.randomUUID()} :: show Progress Spinner")
WorkInfo.State.SUCCEEDED -> Log.e("OBSERVING", "${UUID.randomUUID()} :: stop showing Progress Spinner")
WorkInfo.State.FAILED -> Log.e("OBSERVING", "${UUID.randomUUID()} :: stop showing Progress Spinner")
WorkInfo.State.BLOCKED -> Log.e("OBSERVING", "${UUID.randomUUID()} :: show Progress Spinner")
WorkInfo.State.CANCELLED -> Log.e("OBSERVING", "${UUID.randomUUID()} :: stop showing Progress Spinner")
}
}
Run Code Online (Sandbox Code Playgroud)
我对这项工作的观察如下:-
WorkManager.getInstance(applicationContext)
.getWorkInfoByIdLiveData(myWorkRequest.id)
.observe(lifeCycleOwner, observer)
Run Code Online (Sandbox Code Playgroud)
并记住我的视图模型中当前的 workId
class MyViewModel : ViewModel() {
private var currentWorkInfoId: UUID? = null
fun startWorkTags(lifeCycleOwner: LifecycleOwner, applicationContext: Context) {
val myWorkRequest: OneTimeWorkRequest =
OneTimeWorkRequest.Builder(MyWorker::class.java)
.addTag(WORK_IN_PROGRESS_TAG + "${UUID.randomUUID()}").build()
WorkManager.getInstance(applicationContext)
.beginUniqueWork(
UNIQUE_WORK_NAME,
ExistingWorkPolicy.KEEP,
myWorkRequest
)
.enqueue()
currentWorkInfoId = myWorkRequest.id
}
}
Run Code Online (Sandbox Code Playgroud)
我有以下问题
1)。当我使用时ExistingWorkPolicy.KEEP,我需要知道何时已经有后台工作处于活动状态,这样我就不会记住错误的工作 ID。目前我无条件记住我上次尝试的工作 ID enqueue()。有什么方法可以检测到何时ExistingWorkPolicy.KEEP导致没有新工作开始?
2)。由于当用户退出我的应用程序时,我将当前工作 ID 存储在我的 viewModel 中,因此我丢失了该 ID。当我的用户重新进入我的应用程序时,如何发现我是否有活跃的工作人员?
对于问题 2)。我尝试过使用
WorkManager.getInstance(applicationContext)
.getWorkInfosForUniqueWorkLiveData(UNIQUE_WORK_NAME)
.observe(lifeCycleOwner, observerUnique)
Run Code Online (Sandbox Code Playgroud)
然而,这种方法“看到”所有以前的工作程序执行,我如何识别最新的工作程序实例?
鉴于您只想在 Worker 运行时显示进度旋转器,您可以实现一种更简单的解决方案,其中您的观察者只需检查是否有一个 Worker 处于非最终状态。
observe(this, listOfWorkInfo -> {
// If there are no matching work info, do nothing
if (listOfWorkInfo == null || listOfWorkInfo.isEmpty()) {
return;
}
boolean showProgress = false;
for (WorkInfo workInfo : listOfWorkInfo) {
if (!(workInfo.getState().isFinished())) {
showProgress = true;
}
}
if (showProgress) {
showSpinner();
} else {
hideSpinner();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在其中获取 WorkInfos 列表getWorkInfosForUniqueWorkLiveData()。
另一种解决方案是使用您已经在使用的WorkManager v2.3.0 中引入的新 Progress API 。
这个想法是,一旦你的工作线程启动(在构造函数中),你就发布进度:
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
public class ProgressWorker extends Worker {
private static final String PROGRESS = "PROGRESS";
private static final long DELAY = 1000L;
public ProgressWorker(
@NonNull Context context,
@NonNull WorkerParameters parameters) {
super(context, parameters);
// Set initial progress to 0
setProgressAsync(new Data.Builder().putInt(PROGRESS, 1).build());
}
@NonNull
@Override
public Result doWork() {
try {
// Doing work.
Thread.sleep(DELAY);
} catch (InterruptedException exception) {
// ... handle exception
}
return Result.success();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用已有的观察者来检索进度workInfo.getProgress()。这种情况下的好处来自这样一个事实:只有在工作线程运行时,进度信息才可用。
您仍然可以从 UniqueWorkName 请求所有 WorkInfo,但只有在工作线程正在运行时才会有进度。
当工作线程处于最终状态时,WorkManager 将负责删除进度信息。
| 归档时间: |
|
| 查看次数: |
9309 次 |
| 最近记录: |