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

LiveData没有通知我的服务的(LifecyclerOwner实现)观察者

尉迟栋
2023-03-14

作为前言,我已经有了一个片段,它以与下面相同的方式观察LiveData,并且它工作得很好。出于某种原因,当试图使用服务作为生命周期所有者时,我认为这会导致一个问题,并且没有调用观察者。

我已经在这里检查了答案,但由于我使用的是相同的ViewModel/DAO实例,这不应该是我的问题。(我想?如果我错了请纠正我。)

我有一个从MattCarroll的Hover扩展HoverMenuService的服务。这些服务显示覆盖UI,所以我想观察服务中的一些LiveData来更新这个UI。我让我的服务实现了LifecycleOwner,基本上从源代码中复制了LifecycleService实现,因此我可以将服务用作生命周期所有者,并向LiveData添加观察者。

这是我的服务

class MyHoverMenuService : HoverMenuService(), LifecycleOwner {

    val TAG = "MyHoverMenuService"

    val mDispatcher = ServiceLifecycleDispatcher(this)

    override fun onHoverMenuLaunched(intent: Intent, hoverView: HoverView) {
        Timber.i("onHoverMenuLaunched called.")
        val menu: HoverMenu = MyHoverMenu(this, application, ContextThemeWrapper(this, R.style.AppTheme))
        hoverView.setMenu(menu)
        hoverView.collapse()
    }

    @CallSuper
    override fun onCreate() {
        mDispatcher.onServicePreSuperOnCreate()
        super.onCreate()
    }

    @CallSuper
    override fun onBind(intent: Intent?): IBinder? {
        mDispatcher.onServicePreSuperOnBind()
        return super.onBind(intent)
    }

    @CallSuper
    override fun onStart(intent: Intent?, startId: Int) {
        mDispatcher.onServicePreSuperOnStart()
        super.onStart(intent, startId)
    }

    @CallSuper
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return super.onStartCommand(intent, flags, startId)
    }

    @CallSuper
    override fun onDestroy() {
        mDispatcher.onServicePreSuperOnDestroy()
        super.onDestroy()
    }

    @CallSuper
    override fun getLifecycle(): Lifecycle {
        return mDispatcher.lifecycle
    }


}
class HoverDictionaryScreen(
    private val ownerService: MyHoverMenuService
    , val application:Application
    , val context: Context
) : Content {
    private val applicationContext: Context = context.applicationContext
    lateinit var dictViewModel: DictionaryInterfaceViewModel
    ...
    fun createScreenView(): View {
        val container: ViewGroup = FrameLayout(ContextThemeWrapper(applicationContext, R.style.AppTheme))


        binding = DataBindingUtil.inflate(
            LayoutInflater.from(applicationContext),
            R.layout.fragment_dictionary_interface,
            container,
            false
        )
        dictViewModel = ViewModelProvider
            .AndroidViewModelFactory.getInstance(application)
            .create(DictionaryInterfaceViewModel::class.java)
        dictViewModel.totalEntries.observe(ownerService, Observer { totalEntries ->
            binding.numberOfEntries.text = "Total number of entries in database : $totalEntries"
        })
    ...

当我检查Binding.NumberOfEntries时,没有更新,而且我还检查了观察者没有使用log语句调用。

共有1个答案

陆琦
2023-03-14

好的,所以我注意到我的ownerservice.lifecycle.currentState从未达到start。这是因为扩展服务的HoverMenuService正在重写/删除onStart方法,所以我有:

@CallSuper
override fun onStart(intent: Intent?, startId: Int) {
    mDispatcher.onServicePreSuperOnStart()
    super.onStart(intent, startId)
}

这似乎并没有切断它,但是在ServiceLifeCycleDispatcher.onServicePreSuperOnStart()文档中提到了这可以放在onstart()onstartCommand()中,因此通过将它放入onstartCommand()(在HoverMenuService抽象类中实现),我的服务生命周期现在达到了启动状态,一切都可以工作了。

@CallSuper
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    mDispatcher.onServicePreSuperOnStart()
    return super.onStartCommand(intent, flags, startId)
}
 类似资料:
  • 在livedata的observe方法中有这样一条评论 在给定所有者的生命周期内将给定的观察者添加到观察者列表中。事件在主线程上分派。如果LiveData已经有数据集,它将传递给观察者。 当我尝试向现有livedata实例添加新的观察者时,如果livedata具有数据集,则new观察者的onChanged方法调用。 有什么办法可以避免这种行为吗?我只是不想被通知新的观察员 SingleLiveEv

  • 此外,为什么Viewmodel不能观察到它自己的LiveData的变化?

  • 当项目添加到LiveData列表时,我需要获得一个Observer事件。但据我所知,只有当我用新列表替换旧列表时,事件才会收到。例如,当我执行下一个操作时: 观察者获取事件。但当我将项目添加到值中时,观察者是沉默的。你能给我一些建议吗?

  • 问题内容: 我有以下代码要使用。 尽管这似乎可行,但以下部分是什么意思? 这必须导致对象符合符合以下条件的Observer接口: 如何 结果对象与onChanged方法? 我不知道将接口名称放在lambda表达式前面意味着什么。 谢谢! 问题答案: 这称为SAM转换,该概念有助于与示例中的Java 单一抽象方法接口进行交互。 以下代码创建的实现,其中单个抽象方法是: 另外,但更冗长的是使用obje

  • 我正在寻找在中观察数据的最佳方法。 我正在使用MVVM数据绑定。 存储库: 它从服务器请求数据并返回实时数据。ViewModel必须观察数据更改。 视图模型: ViewModel使用一个来观察来自存储库的的变化。我添加了数据作为源来观察变化,并在它触发后将其删除,以防止在我多次获取数据时多次触发事件。并且必须有一个虚假的观察者来观察,因此触发器的onChange方法。 比方说,我只需要数据来隐藏/

  • 我有一个单独的类来处理数据提取(特别是Firebase),我通常从它返回LiveData对象并异步更新它们。现在我希望将返回的数据存储在ViewModel中,但问题是为了获得所述值,我需要观察从数据提取类返回的LiveData对象。observe方法需要一个LifecycleOwner对象作为第一个参数,但我的ViewModel中显然没有这个对象,而且我知道我不应该在ViewModel中保留对ac