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 中替换它,因此重复...
您需要在创建观察者之前移除观察者。
在搜索了许多其他 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 中替换它,因此重复...
您需要在创建观察者之前移除观察者。