Android: 如何处理WorkManager Rx的结果?
Android: How to handle the result of WorkManager Rx?
我正在使用带有 Rx 的 WorkManager (Android Jetpack) 开发一个 Android 应用程序。
下面是工人 class.
class ImageRxWorker(
appContext: Context,
private val workerParams: WorkerParameters
) : RxWorker(appContext, workerParams) {
override fun createWork(): Single<Result> = Single.create<Result> { emitter -
// do the job
emitter.onSuccess(Result.success())
}
}
运行良好,没有问题。
但我想知道的是如何处理结果?
class MainPresenter(
private val view: MainActivity,
private val workManager: WorkManager = WorkManager.getInstance()
) : MainContract.Presenter {
override fun startWork(): Completable {
view.showToastMessage(R.string.worker_started)
return Completable.create { emitter ->
val uploadWorkRequest = OneTimeWorkRequestBuilder<ImageRxWorker>().build()
workManager.enqueue(uploadWorkRequest)
emitter.onComplete() // This is not exit immediately.
}
}
}
我找到了"addListener"、"result",但我不知道如何使用它们。
我试着用谷歌搜索,但找不到任何好的参考。
有人帮帮我!
我想...我找到了解决方案之一。
有效!!!
但是……它……很丑……而且不聪明……
(在我的应用中,我不使用 LiveData。)
override fun startWork(): Completable {
view.showToastMessage(R.string.worker_started)
return Completable.create { emitter ->
Log.d(TAG, "[WM][Presenter] startWork - start")
val workRequest = OneTimeWorkRequestBuilder<ImageRxWorker>()
.setInputData(workDataOf("TIME" to 1000L))
.build()
workManager.enqueue(workRequest)
while (workManager.getWorkInfoById(workRequest.id).get().state != WorkInfo.State.SUCCEEDED) {
// Should I really polling?
Thread.sleep(1000)
Log.d(TAG, "[WM][Presenter] not yet......")
}
Log.d(TAG, "[WM][Presenter] complete")
emitter.onComplete()
}
}
哇,这是"User One"的回答写的第三个代码。
它工作正常并且看起来比第二个代码更好。
因为我的应用没有使用'LiveData',所以我无法确定这个代码是否有效。
在 "observeForever" 中,我在 Worker 完成后调用 "cancelWorkById"。
正确吗?
override fun startWork(): Completable {
view.showToastMessage(R.string.worker_started)
return Completable.create { emitter ->
Log.d(TAG, "[WM][Presenter] startWork - start")
val workRequest = OneTimeWorkRequestBuilder<ImageRxWorker>()
.setInputData(workDataOf("TIME" to 1000L))
.build()
workManager.enqueue(workRequest)
workManager.getWorkInfoByIdLiveData(workRequest.id).observeForever { workInfo ->
workInfo?.outputData?.getString("key")?.let { data ->
Log.d(TAG, "[WM][Presenter] startWork - complete: $data")
emitter.onComplete()
workManager.cancelWorkById(workRequest.id)
}
}
}
}
你使用 getWorkInfoById 的方法 return 一个 ListenableFuture,而这个 return 一个 LiveData :
您可以通过观察 getWorkInfoByIdLiveData() 编辑的 LiveData return 来简单地观察工作状态,而不是 while 循环,然后在它被触发后调用 emitter.onComplete(),但是您没有LifeCycle 在您的演示者中,因此您应该使用 observeForever() 并注意删除 Observer,
这是一个例子:
workManager.getWorkInfoByIdLiveData(workRequest.id)
.observeForever(object : Observer<WorkInfo> {
override fun onChanged(workInfo : WorkInfo?) {
if(workInfo.state == WorkInfo.State.SUCCEEDED) {
////The Work result is a Success
}
/* Here We remove the Observer if Not needed anymore
'this' here = the Observer */
workManager.getWorkInfoByIdLiveData(workRequest.id)
.removeObserver(this)
}
或者简单地使用由 getWorkInfoById() 编辑的 ListenableFuture return 来获得 CallBack
我正在使用带有 Rx 的 WorkManager (Android Jetpack) 开发一个 Android 应用程序。 下面是工人 class.
class ImageRxWorker(
appContext: Context,
private val workerParams: WorkerParameters
) : RxWorker(appContext, workerParams) {
override fun createWork(): Single<Result> = Single.create<Result> { emitter -
// do the job
emitter.onSuccess(Result.success())
}
}
运行良好,没有问题。 但我想知道的是如何处理结果?
class MainPresenter(
private val view: MainActivity,
private val workManager: WorkManager = WorkManager.getInstance()
) : MainContract.Presenter {
override fun startWork(): Completable {
view.showToastMessage(R.string.worker_started)
return Completable.create { emitter ->
val uploadWorkRequest = OneTimeWorkRequestBuilder<ImageRxWorker>().build()
workManager.enqueue(uploadWorkRequest)
emitter.onComplete() // This is not exit immediately.
}
}
}
我找到了"addListener"、"result",但我不知道如何使用它们。 我试着用谷歌搜索,但找不到任何好的参考。 有人帮帮我!
我想...我找到了解决方案之一。
有效!!!
但是……它……很丑……而且不聪明……
(在我的应用中,我不使用 LiveData。)
override fun startWork(): Completable {
view.showToastMessage(R.string.worker_started)
return Completable.create { emitter ->
Log.d(TAG, "[WM][Presenter] startWork - start")
val workRequest = OneTimeWorkRequestBuilder<ImageRxWorker>()
.setInputData(workDataOf("TIME" to 1000L))
.build()
workManager.enqueue(workRequest)
while (workManager.getWorkInfoById(workRequest.id).get().state != WorkInfo.State.SUCCEEDED) {
// Should I really polling?
Thread.sleep(1000)
Log.d(TAG, "[WM][Presenter] not yet......")
}
Log.d(TAG, "[WM][Presenter] complete")
emitter.onComplete()
}
}
哇,这是"User One"的回答写的第三个代码。 它工作正常并且看起来比第二个代码更好。 因为我的应用没有使用'LiveData',所以我无法确定这个代码是否有效。
在 "observeForever" 中,我在 Worker 完成后调用 "cancelWorkById"。 正确吗?
override fun startWork(): Completable {
view.showToastMessage(R.string.worker_started)
return Completable.create { emitter ->
Log.d(TAG, "[WM][Presenter] startWork - start")
val workRequest = OneTimeWorkRequestBuilder<ImageRxWorker>()
.setInputData(workDataOf("TIME" to 1000L))
.build()
workManager.enqueue(workRequest)
workManager.getWorkInfoByIdLiveData(workRequest.id).observeForever { workInfo ->
workInfo?.outputData?.getString("key")?.let { data ->
Log.d(TAG, "[WM][Presenter] startWork - complete: $data")
emitter.onComplete()
workManager.cancelWorkById(workRequest.id)
}
}
}
}
你使用 getWorkInfoById 的方法 return 一个 ListenableFuture,而这个 return 一个 LiveData :
您可以通过观察 getWorkInfoByIdLiveData() 编辑的 LiveData return 来简单地观察工作状态,而不是 while 循环,然后在它被触发后调用 emitter.onComplete(),但是您没有LifeCycle 在您的演示者中,因此您应该使用 observeForever() 并注意删除 Observer,
这是一个例子:
workManager.getWorkInfoByIdLiveData(workRequest.id)
.observeForever(object : Observer<WorkInfo> {
override fun onChanged(workInfo : WorkInfo?) {
if(workInfo.state == WorkInfo.State.SUCCEEDED) {
////The Work result is a Success
}
/* Here We remove the Observer if Not needed anymore
'this' here = the Observer */
workManager.getWorkInfoByIdLiveData(workRequest.id)
.removeObserver(this)
}
或者简单地使用由 getWorkInfoById() 编辑的 ListenableFuture return 来获得 CallBack