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

时间:2019-09-21 11:42:54

标签: android android-fragments android-lifecycle android-livedata

在搜索了许多其他SO问题并阅读了文章之后,我仍然对为什么我的实现似乎不像其他示例一样感到困惑。

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

但是,在我的片段OnActivityCreated方法中(当片段显示在屏幕上时,该方法被调用了两次),我似乎得到了与调用LifecycleOwner不同的getViewLifecycleOwner()对象相信是我让多个观察者注册到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

3 个答案:

答案 0 :(得分:0)

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

希望它会起作用。

答案 1 :(得分:0)

我已经解决了这个问题。无论如何,谢谢您的回答!

即使其他人不太可能做我所做的事情,我也会把它放在这里!

我的activity_main.xml已包含

"skipLibCheck": true

正在创建Fragment类的实例,然后我通过替换Fragment从而在MainActivity内部立即替换了它,因此重复了...

答案 2 :(得分:0)

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