【发布时间】:2021-07-01 02:09:07
【问题描述】:
场景:我有两个名为 FirstFragment 和 UnitFragment 的片段。我从FirstFragment 到UnitFragment 使用navController.popBackStack(); 选择一个返回到FirstFragmet 的单元,并将单元数据发送到FirstFragment,这是观察单元数据。
这是我的onViewCreated 或FirstFragment:
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (viewModel == null) { // Lazy Initialization
ApiService apiService = ApiServiceProvider.getInstance();
AddNewWareViewModelFactory addNewWareViewModelFactory = new AddNewWareViewModelFactory(apiService);
viewModel = new ViewModelProvider(this, addNewWareViewModelFactory).get(AddWareViewModel.class);
}
Log.i(TAG, "OnViewCreated -----> Called");
viewModel.callNewWare(parentCode);
viewModel.getNewWareResponse().observe(getViewLifecycleOwner(),
resObject -> Log.i(TAG, "API Response LiveData Count -----> " + count++)); // Started From Zero
NavHostFragment navHostFragment = (NavHostFragment) requireActivity()
.getSupportFragmentManager()
.findFragmentById(R.id.container);
binding.button.setOnClickListener(v -> {
if (navHostFragment != null) {
NavController navController = navHostFragment.getNavController();
navController.navigate(FirstFragmentDirections.actionFirstFragmentToUnitFragment());
}
});
if (navHostFragment != null) {
NavController navController = navHostFragment.getNavController();
NavBackStackEntry navBackStackEntry = navController.getCurrentBackStackEntry();
if (navBackStackEntry != null) {
SavedStateHandle savedStateHandle = navBackStackEntry.getSavedStateHandle();
MutableLiveData<Unit> unitLiveData = savedStateHandle.getLiveData("unit_data");
unitLiveData.observe(getViewLifecycleOwner(), unit -> binding.tvUnit.setText(unit.getTitle()));
}
}
}
这是 LogCat 结果:
--- Go to FirstFragment for first time ---
I/FirstFragment: OnViewCreated -----> Called
I/FirstFragment: API Response LiveData Count -----> 0
--- Button clicked to go to UnitFragment to select a unit ---
I/UnitFragment: Selected Unit -----> Meter
--- Come back to FirstFragment ---
I/FirstFragment: OnViewCreated -----> Called
I/FirstFragment: API Response LiveData Count -----> 1
I/FirstFragment: API Response LiveData Count -----> 2
正如您在 LogCat 结果中看到的,每次我单击按钮并转到 UnitFragment 并返回到 FirstFragment 时,onViewCreated 将再次调用,API LiveDataObserver 将被触发两次!!!
我知道 onViewCreated 会再次调用,因为导航组件会替换片段而不是添加片段。但我不知道为什么 LiveData 观察者会被触发两次。
我读了this post,但他似乎忽略了导航组件。
我需要一个解决方案...
- 避免再次调用
onViewCreated代码。 - 避免再次触发 LiveData 观察者。
【问题讨论】:
-
您能否记录下观察者返回的值
resValue并分享这些结果(即您何时看到它变为“Meter”)?此外,在更新UnitFragment中的LiveData对象时,您使用的是set 还是post 语义? -
我已经模拟了您的代码中缺少的部分,它对我来说可以正常工作。没有重复调用观察者。确保您的 API 按预期工作,并且您的实时数据对象仅在收到响应时更改一次。如果不是这种情况,请提供更多详细信息以获得更好的帮助。
标签: java android android-livedata android-architecture-navigation android-mvvm