【发布时间】:2020-07-16 20:55:39
【问题描述】:
Android Studio 4
RxJava2,MVVM。
方法#1
在我的活动中:
val dispose = filmsRxJavaViewModel.filmsListSingle
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe( {// call before .doOnTerminate()
Debug.d(TAG, "initLogic: doOnSubscribe:")
binding.progressBarLayout.containerProgressBarLayout.setVisibility(View.VISIBLE)
})
.doOnTerminate({// call before .subscribe()
Debug.d(TAG, "initLogic: doOnTerminate:")
binding.filmsSwipeRefreshLayout.isRefreshing = false
binding.progressBarLayout.containerProgressBarLayout.setVisibility(View.GONE)
})
// Only after call subscribe() then execute network request
.subscribe({ filmsList -> // success
Debug.d(TAG, "initLogic: subscribe: success")
// Hide swipe to refresh icon animation
if (filmsList.size > 0) { // list<Film>
filmItemListDataBindingAdapter!!.updateData(filmsList)
} else {
binding.filmsRecyclerView.visibility = View.GONE
binding.emptyLayoutContainer.root.visibility = View.VISIBLE
}
}, {// error
throwable ->
Debug.e(TAG, "initLogic: subscribe: error = $throwable")
Toast.makeText(this, throwable.message, Toast.LENGTH_LONG).show()
})
在我的 ViewModel 中:
class FilmsRxJavaViewModel(application: Application) : AndroidViewModel(application) {
companion object {
private val TAG = FilmsRxJavaViewModel::class.java.name
}
lateinit var filmsListSingle: Single<List<Film>>
init {
Debug.d(TAG, "init:")
loadData()
}
fun loadData() {
Debug.d(TAG, "loadData:")
filmsListSingle = TransportServiceRxJava.getFilms()
}
}
还有我的运输和改造界面
fun getFilms() : Single<List<Film>> {
return testRxJavaRestClient.getFilms()
}
import io.reactivex.Single
import retrofit2.http.GET
interface TestRxJavaRestClient {
@GET("films")
fun getFilms(): Single<List<Film>>
}
因此它的工作。很好......但是 Activity 知道线程之间切换的这种方法的问题。
所以我使用了另一种方法。
方法#2
val dispose = filmsRxJavaViewModel.filmsListSingle
.doOnSubscribe( {// call before .doOnTerminate()
Debug.d(TAG, "initLogic: doOnSubscribe:")
binding.progressBarLayout.containerProgressBarLayout.setVisibility(View.VISIBLE)
})
.doOnTerminate({// call before .subscribe()
Debug.d(TAG, "initLogic: doOnTerminate:")
binding.filmsSwipeRefreshLayout.isRefreshing = false
binding.progressBarLayout.containerProgressBarLayout.setVisibility(View.GONE)
})
// Only after call subscribe() then execute network request
.subscribe({ filmsList -> // success
Debug.d(TAG, "initLogic: subscribe: success")
// Hide swipe to refresh icon animation
if (filmsList.size > 0) { // list<Film>
filmItemListDataBindingAdapter!!.updateData(filmsList)
} else {
binding.filmsRecyclerView.visibility = View.GONE
binding.emptyLayoutContainer.root.visibility = View.VISIBLE
}
}, {// error
throwable ->
Debug.e(TAG, "initLogic: subscribe: error = $throwable")
Toast.makeText(this, throwable.message, Toast.LENGTH_LONG).show()
})
在我的 ViewModel 中:
fun loadData() {
Debug.d(TAG, "loadData:")
filmsListSingle = TransportServiceRxJava.getFilms()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
如您所见,我移至 viewModel 线程之间切换。
我认为这是一个正确的方法。只有 viewModel 必须需要在线程之间切换。因此,我的 Activity 仅适用于视图小部件(例如显示 toast)。
这是正确的方法吗?
【问题讨论】:
标签: android retrofit2 rx-java2