Android WorkManager观察进度
我在应用程序中使用WorkManager进行延迟工作。 整个工作被划分为若干个链接的工人,我很难向用户显示工人的进度(使用进度条) 我尝试创建一个标记并将其添加到不同的Worker中,workers内部通过该标记更新进度,但在调试时,我始终获得的进度为“0” 我注意到的另一件事是,每当我开始工作时(即使工人完成了他们的工作),workManager的工作信息列表会越来越大 这是我的密码:Android WorkManager观察进度,android,android-workmanager,Android,Android Workmanager,我在应用程序中使用WorkManager进行延迟工作。 整个工作被划分为若干个链接的工人,我很难向用户显示工人的进度(使用进度条) 我尝试创建一个标记并将其添加到不同的Worker中,workers内部通过该标记更新进度,但在调试时,我始终获得的进度为“0” 我注意到的另一件事是,每当我开始工作时(即使工人完成了他们的工作),workManager的工作信息列表会越来越大 这是我的密码: //inside view model private val workManager = Work
//inside view model
private val workManager = WorkManager.getInstance(appContext)
internal val progressWorkInfoItems: LiveData<List<WorkInfo>>
init
{
progressWorkInfoItems = workManager.getWorkInfosByTagLiveData(TAG_SAVING_PROGRESS)
}
companion object
{
const val TAG_SAVING_PROGRESS = "saving_progress_tag"
}
//inside a method
var workContinuation = workManager.beginWith(OneTimeWorkRequest.from(firstWorker::class.java))
val secondWorkRequest = OneTimeWorkRequestBuilder<SecondWorker>()
secondWorkRequest.addTag(TAG_SAVING_PROGRESS)
secondWorkRequest.setInputData(createData())
workContinuation = workContinuation.then(secondWorkRequest.build())
val thirdWorkRequest = OneTimeWorkRequestBuilder<ThirdWorker>()
thirdWorkRequest.addTag(TAG_SAVING_PROGRESS)
thirdWorkRequest.setInputData(createData())
workContinuation = workContinuation.then(thirdWorkRequest.build())
workContinuation.enqueue()
//inside the Activity
viewModel.progressWorkInfoItems.observe(this, observeProgress())
private fun observeProgress(): Observer<List<WorkInfo>>
{
return Observer { listOfWorkInfo ->
if (listOfWorkInfo.isNullOrEmpty()) { return@Observer }
listOfWorkInfo.forEach { workInfo ->
if (WorkInfo.State.RUNNING == workInfo.state)
{
val progress = workInfo.progress.getFloat(TAG_SAVING_PROGRESS, 0f)
progress_bar?.progress = progress
}
}
}
}
//inside the worker
override suspend fun doWork(): Result = withContext(Dispatchers.IO)
{
setProgress(workDataOf(TAG_SAVING_PROGRESS to 10f))
...
...
Result.success()
}
//内部视图模型
private val workManager=workManager.getInstance(appContext)
内部val ProgressWorkInfo项目:LiveData
初始化
{
progressWorkInfoItems=workManager.getWorkInfosByTagLiveData(标记\保存\进度)
}
伴星
{
const val TAG_SAVING_PROGRESS=“SAVING_PROGRESS_TAG”
}
//方法内部
var workContinuation=workManager.beginWith(OneTimeWorkRequest.from(firstWorker::class.java))
val secondWorkRequest=OneTimeWorkRequestBuilder()
secondWorkRequest.addTag(标记保存进度)
secondWorkRequest.setInputData(createData())
workContinuation=workContinuation.then(secondWorkRequest.build())
val thirdWorkRequest=OneTimeWorkRequestBuilder()
thirdWorkRequest.addTag(标记保存进度)
thirdWorkRequest.setInputData(createData())
workContinuation=workContinuation.then(thirdWorkRequest.build())
workContinuation.enqueue()
//活动内部
viewModel.ProgressWorkInfo.observe(这是observeProgress())
私人娱乐observeProgress():Observer
{
返回观察者{listOfWorkInfo->
如果(listOfWorkInfo.isNullOrEmpty()){return@Observer }
listOfWorkInfo.forEach{workInfo->
if(WorkInfo.State.RUNNING==WorkInfo.State)
{
val progress=workInfo.progress.getFloat(标记保存进度,0f)
进度条?进度=进度
}
}
}
}
//工人内部
重写suspend fun doWork():Result=withContext(Dispatchers.IO)
{
设置进度(workDataOf(标记保存进度至10f))
...
...
结果:成功()
}
设置进度的方法是观察单个工人的中间进度(如中所述):
只能在ListenableWorker运行时观察和更新进度信息
因此,只有在工作人员处于活动状态时,进度信息才可用(例如,它不处于像成功
、失败
和取消
)这样的终端状态)
我的建议是使用工人的唯一ID来识别链中哪个工人尚未处于终端状态。您可以使用
WorkRequest
的方法来检索其唯一ID。该setProgress
方法用于观察单个工作者的中间进度(如中所述):
只能在ListenableWorker运行时观察和更新进度信息
因此,只有在工作人员处于活动状态时,进度信息才可用(例如,它不处于像成功
、失败
和取消
)这样的终端状态)
我的建议是使用工人的唯一ID来识别链中哪个工人尚未处于终端状态。您可以使用
WorkRequest
的方法来检索其唯一ID。根据我的分析,我发现您总是得到0
设置在worker的setProgress
中的doWork()
之前,然后它将丢失,您永远无法在侦听器中获得该值。这可能是因为工作进程的状态现在为“已成功”Result.success()
- 工人正在几秒钟内完成工作
class Worker1(context: Context, workerParameters: WorkerParameters) : Worker(context,workerParameters) {
override fun doWork(): Result {
setProgressAsync(Data.Builder().putInt("progress",10).build())
for (i in 1..5) {
SystemClock.sleep(1000)
}
setProgressAsync(Data.Builder().putInt("progress",50).build())
SystemClock.sleep(1000)
return Result.success()
}
}
在上述代码中
- 如果只删除第一个sleep方法,那么侦听器只会获得progres
50
- 如果只删除第二个sleep方法,则侦听器只获得进度
10
- 如果同时删除这两个选项,则会得到默认值
0
class Worker1(context: Context, workerParameters: WorkerParameters) : Worker(context,workerParameters) {
override fun doWork(): Result {
for (i in 1..5) {
Log.e("worker", "worker1----$i")
}
return Result.success(Data.Builder().putInt("progress",50).build())
}
}
class Worker2(context: Context, workerParameters: WorkerParameters) : Worker(context,workerParameters) {
override fun doWork(): Result {
for (i in 5..10) {
Log.e("worker", "worker1----$i")
}
return Result.success(Data.Builder().putInt("progress",100).build())
}
}
活动内部
workManager = WorkManager.getInstance(this)
workRequest1 = OneTimeWorkRequest.Builder(Worker1::class.java)
.addTag(TAG_SAVING_PROGRESS)
.build()
workRequest2 = OneTimeWorkRequest.Builder(Worker2::class.java)
.addTag(TAG_SAVING_PROGRESS)
.build()
findViewById<Button>(R.id.btn).setOnClickListener(View.OnClickListener { view ->
workManager?.
beginUniqueWork(TAG_SAVING_PROGRESS,ExistingWorkPolicy.REPLACE,workRequest1)
?.then(workRequest2)
?.enqueue()
})
progressBar = findViewById(R.id.progressBar)
workManager?.getWorkInfoByIdLiveData(workRequest1.id)
?.observe(this, Observer { workInfo: WorkInfo? ->
if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
val progress = workInfo.outputData
val value = progress.getInt("progress", 0)
progressBar?.progress = value
}
})
workManager?.getWorkInfoByIdLiveData(workRequest2.id)
?.observe(this, Observer { workInfo: WorkInfo? ->
if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
val progress = workInfo.outputData
val value = progress.getInt("progress", 0)
progressBar?.progress = value
}
})
workManager=workManager.getInstance(此)
workRequest1=OneTimeWorkRequest.Builder(Worker1::class.java)
.addTag(标记保存进度)
.build()
workRequest2=OneTimeWorkRequest.Builder(Worker2::class.java)
.addTag(标记保存进度)
.build()
findViewById(R.id.btn).setOnClickListener(View.OnClickListener{View->
工作经理?。
开始工作(标记保存进度,现有工作策略。替换,工作请求1)
?然后(工作请求2)
?.排队()
})
progressBar=findViewById(R.id.progressBar)
workManager?.getWorkInfoByIdLiveData(workRequest1.id)
?观察(观察者{workInfo:workInfo?->
if(workInfo!=null&&workInfo.state==workInfo.state.successed){
val progress=workInfo.outputData
val value=progress.getInt(“progress”,0)
progressBar?进度=值
}
})
workManager?.getWorkInfoByIdLiveData(workRequest2.id)