【问题标题】:What happen with LiveData after delay延迟后 LiveData 会发生什么
【发布时间】:2021-08-10 09:28:20
【问题描述】:

这是我的代码:

HomeFragment

...

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    homeViewModel.myTest.observe(viewLifecycleOwner) {
        Log.d(TAG, "myTest=$it")
    }

    lifecycleScope.launch {
        homeViewModel.doSomethingForMyTest()
    }

}
...

HomeViewModel

...

private val _myTest = MutableLiveData<String>()
val myTest: LiveData<String> = _myTest

fun doSomethingForMyTest() {
    Log.i(TAG, "doSomethingForMyTest start: ${System.currentTimeMillis()}")
    (1..3).forEach {
        _myTest.value = it.toString()
    }
    Log.i(TAG, "doSomethingForMyTest end: ${System.currentTimeMillis()}")
}

...

log

I/HomeViewModel: doSomethingForMyTest start: 1628586904976
I/HomeViewModel: doSomethingForMyTest end: 1628586904977
D/HomeFragment: myTest=3

如果在调用函数之前添加延迟,如下所示:

HomeFragment

...

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    homeViewModel.myTest.observe(viewLifecycleOwner) {
        Log.d(TAG, "myTest=$it")
    }
    lifecycleScope.launch {
        delay(1)
        homeViewModel.doSomethingForMyTest()
    }
}

...

log

I/HomeViewModel: doSomethingForMyTest start: 1628587129413
D/HomeFragment: myTest=1
D/HomeFragment: myTest=2
D/HomeFragment: myTest=3
I/HomeViewModel: doSomethingForMyTest end: 1628587129414

如你所见,我不知道有什么区别......

为什么日志不同?

【问题讨论】:

    标签: android android-livedata


    【解决方案1】:

    您缺少两件事:

    viewLifecycleOwner - 在onViewCreated 期间,它仍处于INITIALIZED 状态,因此在片段移动到STARTED 状态之前,您的 liveData 观察者不会收到更新。

    lifecycleScope - 它由Dispatchers.Main.immediate 支持,这意味着当您已经在正确的上下文(ui 线程)中时,launch 会立即执行,直到第一次暂停调用。

    在第一种情况下,您添加观察者,然后您的三个更新立即运行,但观察者尚未激活,因此它仅在片段 viewLifecycleOwner 移动到 STARTED 状态时接收最后一个值。

    在第二种情况下,delay 是一个暂停点,因此您的launch 无法内联执行。由于lifecycleScopeDispatchers.Main 支持,因此必须将调用延迟到下一个ui-thread 周期,在此期间片段已经处于STARTED 状态,因此您的观察者处于活动状态并实时接收每个更新。

    【讨论】:

    • 谢谢,我知道observe 方法是如何工作的。 “只有当所有者处于 Lifecycle.State.STARTED 或 Lifecycle.State.RESUMED 状态(活动)时,观察者才会收到事件。”还有delay,也许我应该阅读更多的协程文档。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2019-06-23
    相关资源
    最近更新 更多