【问题标题】:Is there any benefits to using LiveData rather than a regular callback?使用 LiveData 而不是常规回调有什么好处吗?
【发布时间】:2020-08-27 08:59:23
【问题描述】:
我有一个允许用户登录的应用。用户数据保存在数据库中。 MainActivity 实现了一个接口 OnUserCreationCallback:
class MainActivity implements OnUserCreationCallback {
//Unrelated code
@Override
void setUser(boolean created) {
if(created) {
//Display welcome message
}
}
}
一旦在数据库中创建了用户,setUser() 方法就会触发并且用户会收到一条欢迎消息。这按预期工作。我的问题是,在创建用户时可以观察到实现 ViewModel 和 LiveData 是否有任何真正的好处?我说的只是这个特定的操作,而不是多次更改的操作。这是一次性操作。
【问题讨论】:
标签:
android
android-livedata
android-architecture-components
android-viewmodel
【解决方案1】:
如果您在 Activity 销毁后保留回调,这可能会泄漏您的 Activity。例如,如果您在配置更改期间保留您的用户存储库或其他任何东西,它将继续引用回调,即活动,并且它永远不会真正被销毁。
另一方面,LiveData 具有生命周期意识,并将根据其注册的生命周期所有者取消订阅,例如当活动被销毁时。
另一个人也发表了很好的观点。这基本上是 MVP 与 MVVM 的争论。
【解决方案2】:
是的:
Livedata 具有生命周期感知能力。
这意味着如果片段被分离或用户退出应用程序,观察者也被分离。
在您的情况下,这可能会阻止用户退出应用程序并获得空指针异常,因为主机不存在。在更复杂的情况下,它会帮助您更好地协调事件。
LiveData 是一种使用观察者进行异步编程的方法。从本地 db 到 View 你可以观察一个实时数据或使用 Coroutines 来获取数据,结果是一样的,你必须判断什么时候在协程中得到结果更好,或者什么时候有观察者更好。
我之所以这么说是因为您不需要 ViewModel,它是 Jetpack 的一部分,但是如果您的 DAO 返回 LiveData,那么您可以直接从视图中观察到它(顺便说一下,这将是糟糕的架构)或者您可以使用 Presenter。
@Dao
interface EntityDao {
@Query(/*SELECT ALL*/)
suspend fun getAll(): List<Entity>
@Query(/*SELECT ALL*/)
fun getAll(): LiveData<List<Entity>>
}
还有其他含义,要测试实时数据,您需要一些辅助方法或使用 espresso,但要测试暂停功能,您可以使用 roboelectric 或 runBlockingTest 套件