我们知道,LiveData是有生命周期意识的。如果发生配置更改,LiveData对象不会每次都重新从数据库(本地/远程)查询数据,只有在数据有更新时才会更新。
最近我开始使用Kotlin Flow,我必须承认它非常适合用于数据层,即在repo中实现,以便能通知ViewModel。但我也在ViewModel / View层中使用了Kotlin Flow,以便可以根据其状态(sealed class实现)直接在Fragment中collect Flow对象。这种使用Flow的问题是,每次发生配置更改时都会从数据库(本地/远程)检索数据。
在这种情况下应该怎么做? 是否有一种方法可以避免在使用Flow时重新查询,还是应该只在ViewModel / View层中使用LiveData?
示例代码:
在这种情况下应该怎么做? 是否有一种方法可以避免在使用Flow时重新查询,还是应该只在ViewModel / View层中使用LiveData?
示例代码:
sealed class Status<T> {
class Processing<T> : Status<T>()
data class Completed<T>(val value: T) : Status<T>()
data class Error<T>(val error: String) : Status<T>()
companion object {
fun <T> processing() = Processing<T>()
fun <T> completed(value: T) = Completed(value)
fun <T> error(error: String) = Error<T>(error)
}
}
代码库:
class Repo(database: LocalDatabase){
fun retrieveUsersData() = flow<Status<List<Users>>>{
emit(Status.processing())
database.dao.getUsers().collect{
// Assume db queries successfully and returns list of users
emit(Status.completed(it))
}
}.catch {
emit(Status.error(it.error.toString()))
}.flowOn(Dispatchers.IO)
}
ViewModel:
class MyViewModel(application: Application): AndroidViewModel(application)
{
private val db = LocalDatabase.getInstance(application)
private val repo = Repo(db)
val usersData= repo.retrieveUsersData(dataCollectionType)
}
片段:
class UsersFragment: Fragment(){
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Assume all the declarations are done properly
coroutineScope.launch {
retrieveUsersData()
}
}
private suspend fun retrieveUsersData(){
viewModel.retrieveUsersData().collect{ status ->
// Based on the Status do the actions.
// When Status is Completed set the data to the adapter.
}
}
} // end of Fragment