当前位置: 首页 > 知识库问答 >
问题:

Android LiveData的Observer未调用(但使用了observeForever)

桂高昂
2023-03-14

该片段仅停止(当您从详细信息返回到列表时恢复)。它不是分离的,不是被破坏的,它的视图仍然存在,等等,所以observeForever-observer可以很好地更新UI(即使不可见)。

但是我想使用普通observe()的“添加并忘记”方法,在这里我不需要删除观察者。

有人知道为什么不叫观察者吗?如前所述,片断只是停止了,视图仍然存在(当更改发生在相同的活动中而不是在不同的活动中时,才调用它)。

由于observeForever()正在工作,我只能想到一个bug生命周期,其中观察者在返回时被标记为“stopped”,而不是“reserve”?

如所问,下面是将RealmResult作为LiveData获取的代码(来自realm的一篇博客文章):

Realm.getDefaultInstance()
  .where<Model>()
  .findAllAsync()
  .asLiveData()

fun <T : RealmModel> RealmResults<T>.asLiveData() = RealmResultsRealmData(this)

class RealmResultsRealmData<T : RealmModel>(private val results: RealmResults<T>) : LiveData<RealmResults<T>>() {

    private val listener = RealmChangeListener<RealmResults<T>> { realmResults ->
        value = if (realmResults.isValid) realmResults else null
    }

    // region LiveData

    override fun onActive() {
        results.addChangeListener(listener)
    }

    override fun onInactive() {
        results.removeChangeListener(listener)
    }

    // endregion
}

一切正常。我的viewmodeloncleared()中调用realm.close(),所以这也应该很好。

如前所述,我不认为问题出在领域端,因为它在使用observeForever()时起作用,而在LiveData上使用普通的observe()时则不起作用。Realm只填充LiveData,并验证其工作(使用ObserveForever())。

我的最佳猜测仍然是使用observe()时观察者的生命周期。但我不明白为什么当片段被“恢复”时不调用它。文档中说“观察者从非活动状态变为活动状态时也会收到更新”。

它没有定义什么是“活动”状态,但我想它至少是“开始”的,当我从细节活动回来时,我的片段就会进入这个状态。所以应该使用LiveData的最新值来调用观察者?相反,当使用observeForever()时,当我还在details-activity(因为片断只是停止了,但仍然处于活动状态?!)时,就会立即调用观察者。

共有1个答案

廉志强
2023-03-14

看来AddChangeListener()没有调用具有当前值的侦听器。

来自realm-examples的LiveRealmResults-class在构造函数中手动执行此操作(当结果已经加载时,因此仅用于同步查询)。

if (results.isLoaded) {
    // we should not notify observers when results aren't ready yet (async query).
    // however, synchronous query should be set explicitly.
    value = results
}

对于async-ones,只有在查询返回时才调用侦听器(因此这在大多数情况下都起作用,因为LiveData已经处于活动状态(OnActive()已经从系统中调用,并且已经添加了侦听器)。

因此我的UI(观察LiveData)没有得到通知,仍然显示旧的数据。

变通办法

我通过将示例构造函数中的相同行添加到onactive()(复制自示例)来解决这一问题。这样,当livedata激活时,就会使用当前值调用侦听器(但在未加载结果的初始调用时不会调用--因此不会进行双重调用)。

override fun onActive() {
    super.onActive()

    if (results.isValid) { // invalidated results can no longer be observed.
        results.addChangeListener(listener)

        if (results.isLoaded) {
            value = results
        }
    }
}
 类似资料:
  • 我正面临一个让我发疯的问题。 我尝试在onDestroyView()中删除观察者,它可以工作,观察者被删除,但是一旦片段再次进入onActivityCreated()中,并且我观察到livedata,观察者就会立即被触发...我总是使用“ViewLifecyCleOwner”作为所有者。 如果我返回实例化片段,是否有任何方法可以取消liveData的执行? 我所有的frag都扩展了ScopeFra

  • 我有如下测试方法: 是我要模拟并返回空映射的方法。但我收到的失败信息说 需要但未调用MyClass.MethodUsedInMethodBeingTest() .

  • 我知道这个问题已经被问过很多次并得到回答,我的问题与Firebase控制台告诉我,即使我的应用成功接收注册令牌,我的应用也从未与其服务器通信有关。 当我卸载并重新安装我的应用程序时,它会调用FirebaseMessagingService类(或者更确切地说是从它扩展的类)的onNewToken()方法。 甚至FirebaseInstanceId.getInstance()。getInstanceI

  • 我正在测试我的自定义备份代理。下面是我在模拟器&Eclipse ADT中的测试 null 已启用ADB shell bmgr ADB shell bmgr backup App_Package ADB shell bmgr运行-------------运行备份(调用BackupAgent.onBackup) adb uninstall app_package------------备份后卸载应用程

  • 我是写测试和使用Mockito的新手。我在Stackoverflow上阅读了类似的主题,并做了建议的更改,确保所考虑的类/接口/方法是开放的。 我试图跟踪这个 模仿构造函数注入的依赖项 这是我目前想出来的测试 但我一直得到的回应是 即使我在测试中没有提到这种方法,我也得到了这种反应。这是我的演示者注册方法。我已经改变了类/接口 同样地 这里是接口 感谢您的帮助。

  • 我正在做一个单元测试,在我的应用程序中的类,它只是一个简单的类,我认为我做的一切都是正确的,但测试失败了,说: 需要但未调用:MContextWeakReference.Get();->在rahmat.com.app.utility.backwardcompatibility.StringResourceUtilTest.GetString(StringResourceUtilTest.java: