Android LiveData 在片段中创建多个观察者

Android LiveData creating multiple observers in fragment

在搜索了许多其他 SO 问题并阅读了文章之后,我仍然不明白为什么我的实现似乎不像其他示例那样执行。

我读到建议在片段内注册任何 LiveData 观察器时使用 getViewLifecycleOwner() 以正确处理片段的生命周期。

但是,在我的片段 OnActivityCreated 方法中(当片段显示在屏幕上时该方法被调用两次)我似乎从 getViewLifecycleOwner() 的调用中得到了不同的 LifecycleOwner 对象我相信这是我让多个观察者注册到我的 LiveData 对象的原因。

如何防止这种情况发生/我做错了什么?

我在代码中添加了很多日志记录,如下所示:

MainActivity

   public class MainActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragment, new LiveDataTestFragment())
                    .commit();

            Log.d("debugger2", "Activity: " + this.hashCode());
        }
    }

LiveDataTestFragment

public class LiveDataTestFragment extends Fragment {

    private LiveDataViewModel viewModel;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_live_data_test, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        viewModel = ViewModelProviders.of(getActivity()).get(LiveDataViewModel.class);

        Log.d("debugger2", "ViewModel: " + viewModel.hashCode());

        LiveData<String> liveData = viewModel.getLiveData();
        Log.d("debugger2", "LiveData: " + liveData.hashCode());

        LifecycleOwner lifecycleOwner = getViewLifecycleOwner();
        Log.d("debugger2", "LifeCycleOwner: " + lifecycleOwner.hashCode());

        liveData.observe(lifecycleOwner, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.d("debugger2", "observer hash: " + this.hashCode());
            }
        });
    }
}

Logcat:

D: Activity: 242098714
D: ViewModel: 149122972
D: LiveData: 58736037
D: LifeCycleOwner: 50378106
D: ViewModel: 149122972
D: LiveData: 58736037
D: LifeCycleOwner: 245135826
D: observer hash: 204470220
D: observer hash: 226765595
new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.d("debugger2", "observer hash: " + this.hashCode());
            }
        }

可能是你的观察者的这一部分负责创建多个hashCode() 您可以创建此 observer 一次,如果需要使用以下代码多次调用它:

private Observer<String> singleObserver = Observer<String>() {
                @Override
                public void onChanged(String s) {
                    Log.d("debugger2", "observer hash: " + this.hashCode());
                }
}

并像这样使用它:

// your previous code
LiveData<String> liveData = viewModel.getLiveData();
liveData.observe(lifecycleOwner, singleObserver);
// rest of your code

希望它能奏效。

我已经弄清楚这个问题了。无论如何感谢您的回答!

我会把这个问题放在这里,即使其他人不太可能做我所做的!

我的activity_main.xml包含

<fragment
    android:name="com.test.livedatatestapp.LiveDataTestFragment"
    android:id="@+id/fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

它正在创建 Fragment class 的一个实例,然后我通过替换 Fragment 立即在 MainActivity 中替换它,因此重复...

您需要在创建观察者之前移除观察者。