问题

摘要:导航到新的片段,弹出新的片段,然后返回原始片段之后,在片段中触发了多个 LiveData 观察者

详细信息:该体系结构由 MainActivity 组成,该托管宿主 HomeFragment 作为MainActivity的导航图中的开始目标。 HomeFragment中有一个以编程方式膨胀的 PriceGraphFragment HomeFragment 正在使用导航组件来启动新的子片段 ProfileFragment 。背面按一下,将弹出ProfileFragment,应用程序返回到承载PriceGraphFragment的HomeFragment。 PriceGraphFragment是多次调用Observer的地方。

我正在记录观察者发出的HashMap的哈希码,当我转到配置文件Fragment,弹出配置文件Fragment并返回价格Fragment时,它显示2个唯一的哈希码。这与我在不启动配置文件Fragment的情况下旋转屏幕时从HashMap中看到的一个哈希码相反。

执行

  • 导航组件,用于在HomeFragment中启动新的ProfileFragment。
    view.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_homeFragment_to_profileFragment, null))
  • 在Fragment(PriceGraphFragment)中创建
  • ViewModel 。 ViewModel已被记录,并且具有多个Observer的数据仅在ViewModel中初始化了一次数据。
    override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) priceViewModel = ViewModelProviders.of(this).get(PriceDataViewModel::class.java)}
  • 在原始片段(PriceGraphFragment)中监听 ViewModel 中的数据。这被多次调用,但是,仅在加载Fragment时才具有一个Observer。
    priceViewModel.graphLiveData.observe(this, Observer { priceGraphDataMap: HashMap<Exchange, PriceGraphLiveData>? -> // This is being called multiple times.})

  • 尝试的解决方案
  • onCreate()方法中创建片段 ViewModel priceViewModel = ViewModelProviders.of(this).get(PriceDataViewModel::class.java)
  • 使用Fragment的 Activity 和子Fragment的父Fragment创建ViewModel。priceViewModel = ViewModelProviders.of(activity!!).get(PriceDataViewModel::class.java)priceViewModel = ViewModelProviders.of(parentFragment!!).get(PriceDataViewModel::class.java)
  • 将创建观察者的方法移动到片段的 onCreate() onActivityCreated()方法。
  • viewLifecycleOwner方法中为 LifecycleOwner 使用this而不是observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
  • 将HashMap数据存储为与Fragment相对的ViewModel中的重复项。
  • 使用ChildFragmentManagerSupportFragmentManager(在“ Activity ”级别)启动子片段。

  • 相似的问题和建议的解决方案
  • https://github.com/googlesamples/android-architecture-components/issues/47
  • https://medium.com/@BladeCoder/architecture-components-pitfalls-part-1-9300dd969808
  • https://plus.google.com/109072532559844610756/posts/Mn9SpcA5cHz

  • 下一步
  • 也许问题与在父片段的(HomeFragment)onViewCreated()中创建嵌套的 ChildFragment (PriceGraphFragment)有关?

  • 父片段
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        user = viewModel.getCurrentUser()
         if (savedInstanceState == null) {
             fragmentManager
                    ?.beginTransaction()
                    ?.replace(binding.priceDataContainer.id,
                       PriceGraphFragment.newInstance())
                    ?.commit()
    }
    
  • 测试用RxJava observables替换LiveData对象。
  • 最佳答案

    这基本上是体系结构中的错误。您可以阅读有关它的更多信息here。您可以通过使用getViewLifecycleOwner而不是observer中的方法解决此问题。

    像这样:

    mViewModel.methodToObserve().observe(getViewLifecycleOwner(), new Observer<Type>() {
            @Override
            public void onChanged(@Nullable Type variable) {
    

    并将此代码放在onActivityCreated()中,因为使用getViewLifecycleOwner需要一个 View 。

    关于android - 弹出 fragment 后的多个LiveData观察者,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51892478/

    10-12 13:46