即使数据没有变化,LiveData 观察者的 onChanged 也会在活动轮换时被调用

Adr*_*zka 8 android viewmodel android-livedata

我工作ViewModelsLiveDataAndroid应用中,我想用它来跟踪数据,即使当屏幕旋转时的活动。这很有效,但有一个我无法解决的问题。在 Activity 的onCreate方法中,我为包含对象列表的 LiveData 注册了一个观察者,如果加载了数据,它应该只向活动添加一个 Fragment。然后,如果savedInstanceState为空,我只重新加载数据,这应该会阻止它在屏幕旋转时重新加载。这看起来像这样:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        model = ViewModelProviders.of(this).get(MainActivityModel.class);
        observeList();
        if (savedInstanceState == null) {
            loadList(); //Reload the list and call postValue() on the LiveData.
        }
    }

    private void observeList() {
        model.getList().observe(this, new Observer<ArrayList<Object>>(){
            @Override
            public void onChanged(@Nullable ArrayList<Object> objects) {
                //Add list fragment whenever data changes.
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.container, ListFragment.getInstance(list))
                        .commit();
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

根据我的理解,ListFragment 只应在数据更改时显示。但是,经过一些调试后,似乎onChanged每次旋转屏幕时都会调用 observeList 方法中的方法。此外,我检查了实际列表是否已更改并且完全相同,完全没有区别,甚至从来没有postValue() 或setValue()方法调用。因此,我不知道为什么会在屏幕旋转时调用 onChanged 方法。

这也仅在列表包含某些内容时发生。当应用程序启动时,列表在loadList()被调用之前的长度为 0 。当观察者在此状态注册时,不会调用 onChanged 方法。

我最好的猜测是该onChanged方法被触发,因为在注册观察者时列表不为空,因此观察者可能认为数据发生了变化。谁能解释为什么会发生这种情况?

Paw*_*wel 7

这是按预期工作的。从实时数据概述

确保活动或片段具有可在其变为活动状态后立即显示的数据。一旦应用程序组件处于 STARTED 状态,它就会从它正在观察的 LiveData 对象接收最新的值。只有在设置了要观察的 LiveData 对象时才会发生这种情况。

尽管缺少代码片段 -loadList应该是 ViewModel 本身的一部分,而不是一种活动方法。