我有一个要在其中实现Kotlin Couroutines的android应用程序,我所困惑的是在哪里使用协程。我的viewModel为-
class PostViewModel : ViewModel() {
var postPagedList: LiveData<PagedList<UnsplashImageDetails>>? = null
private var postLiveDataSource: LiveData<PageKeyedDataSource<Int, UnsplashImageDetails>>? = null
var popularPagedList: LiveData<PagedList<UnsplashImageDetails>>? = null
private var popularLiveDataSource: LiveData<PageKeyedDataSource<Int, UnsplashImageDetails>>? = null
init {
val postDataSourceFactory = PostDataSourceFactory()
val popularDataSourceFactory = PopularDataSourceFactory()
postLiveDataSource = postDataSourceFactory.getPostLiveDataSource()
popularLiveDataSource = popularDataSourceFactory.getPopularLiveDataSource()
val config: PagedList.Config = (PagedList.Config.Builder()).setEnablePlaceholders(false)
.setPageSize(PostDataSource().PAGE_SIZE).build()
val configPop: PagedList.Config = (PagedList.Config.Builder()).setEnablePlaceholders(false)
.setPageSize(PopularDataSource().PAGE_SIZE).build()
postPagedList = LivePagedListBuilder(postDataSourceFactory, config).build()
popularPagedList = LivePagedListBuilder(popularDataSourceFactory, configPop).build()
}
}
在此活动中或在通过改造获取数据的存储库类中,应该在哪里使用异步方法。
答案 0 :(得分:4)
在这种情况下,协程应该在PostDataSource
中触发。如果您想知道是否应该在此处使用GlobalScope
,则答案是否定的。有一种更优雅的方式可以做到这一点。您还应该找到一种取消作业的方法,以防止内存泄漏。这就是为什么我在这里写了this article来解决这个特定问题的原因。
您应该找到一种方法来管理ViewModel
中的协程,但是您应该在DataSource
中触发它们。
最好的方法。
创建数据类:
data class Listing<T>(
val pagedList: LiveData<PagedList<T>>,
val networkState: LiveData<NetworkState>, //initial state
val refreshState: LiveData<NetworkState>, // second state, after first data loaded
val refresh: () -> Unit, // signal the data source to stop loading, and notify its callback
val retry: () -> Unit, // remake the call
val clearCoroutineJobs: () -> Unit // the way to stop jobs from running since no lifecycle provided )
enum class Status {
RUNNING,
SUCCESS,
FAILED
}
@Suppress("DataClassPrivateConstructor")
data class NetworkState private constructor(
val status: Status,
val msg: String? = null
) {
companion object {
val LOADED =
NetworkState(Status.SUCCESS)
val LOADING =
NetworkState(Status.RUNNING)
fun error(msg: String?) = NetworkState(
Status.FAILED,
msg
)
}
}
然后,您的数据源工厂应该类似于this。
此方法的好处是,您可以在onCleared
的{{1}}方法中取消作业:
ViewModel
请注意,这也是Igit在此github repo中提供的指南。
我同意该解决方案应该更简单,但是如果您考虑一下,协程和并发总体与简单性无关,那么您将在此处处理线程。