+1
Các cách thay thế public progress của AsyncTask bằng RxJava
Hi mọi người, mình đang học thêm về RxJava/RxAndroid. Giả sử trong project của mình có 1 AsyncTask và mình cần phải convert nó sang Rx, mình có AsyncTask đếm từ 1 tới 10 sau mỗi giây như sau:
class MyAsyncTask : AsyncTask<Void, Int, Unit>() {
override fun doInBackground(vararg params: Void?) {
Util.log("doInBackground")
(1..10).forEach {
publishProgress(it)
SystemClock.sleep(1000)
}
}
override fun onProgressUpdate(vararg values: Int?) {
Util.log("onProgressUpdate value = ${values[0]}")
}
override fun onPostExecute(result: Unit?) {
Util.log("onPostExecute")
}
override fun onPreExecute() {
Util.log("onPreExecute")
}
}
Và kết quả log ra như vầy:
10-26 10:30:43.258 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onPreExecute
10-26 10:30:43.278 14892-14954/com.example.rxprogressasynctask E/TAG: [Background] doInBackground
10-26 10:30:43.308 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 1
10-26 10:30:44.278 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 2
10-26 10:30:45.278 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 3
10-26 10:30:46.278 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 4
10-26 10:30:47.278 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 5
10-26 10:30:48.288 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 6
10-26 10:30:49.288 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 7
10-26 10:30:50.288 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 8
10-26 10:30:51.288 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 9
10-26 10:30:52.288 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onProgressUpdate value = 10
10-26 10:30:53.288 14892-14892/com.example.rxprogressasynctask E/TAG: [Main] onPostExecute
Để convert AsyncTask này qua RxJava thì mình sẽ viết theo các cách sau: Cách 1: Sử dụng duy nhất 1 Observable với các hàm tương ứng: onNext() thay cho onProgressUpdate() và onComplete() thay cho onPostExecute()
class MyRxTask1 {
fun execute() {
Util.log("onPreExecute")
Observable.just(arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
.flatMap {
Util.log("doInBackground")
Observable.create<Int> { emitter ->
it.forEach {
emitter.onNext(it)
SystemClock.sleep(1000)
}
emitter.onComplete()
}
}
.applySchedulers()
.subscribe({
// onNext
Util.log("onProgressUpdate value = $it")
}, {
// onError
}, {
// onComplete
Util.log("onPostExecute")
})
}
private fun <T> Observable<T>.applySchedulers(): Observable<T> {
return this.subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread())
}
}
Cách 2: Sử dụng kết hợp Observable và 1 loại Observable khác là PublishSubject
class MyRxTask2 {
fun execute() {
val subject = PublishSubject.create<Int>()
subject.observeOn(AndroidSchedulers.mainThread()).subscribe {
Util.log("onProgressUpdate value = $it")
}
Util.log("onPreExecute")
Observable.just(arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
.doOnNext {
Util.log("doInBackground")
it.forEach {
subject.onNext(it)
SystemClock.sleep(1000)
}
}
.applySchedulers()
.subscribe {
// onNext
Util.log("onPostExecute")
}
}
private fun <T> Observable<T>.applySchedulers(): Observable<T> {
return this.subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread())
}
}
Câu hỏi là cách đầu tiền có phải cách tốt nhất? Cách thứ 2 có ổn không? Và có còn cách nào khác để implement việc convert từ AsyncTask nữa không? Thanks mọi người!
Thêm một bình luận