Java Android Studio中Fragment间使用ViewModel时全局变量为null问题
问题根因
你遇到的空指针本质是Fragment视图已销毁,但LiveData观察者仍收到回调,触发逻辑为:
- 你最初将Observer的生命周期绑定到Activity,只要Activity不销毁,Observer就会一直处于活跃状态
- FirstFragment切到其他Fragment时,会回调
onDestroyView()将binding置为null,此时如果发送端更新了LiveData,仍会触发Observer的onChanged回调,访问已为null的binding就会抛出空指针
你之前替换生命周期所有者未生效,大概率是旧的绑定了Activity生命周期的Observer没有被移除,重复注册了多个Observer。
解决方案
按照以下步骤修改即可:
- 先清理App进程,完全卸载重装一次,避免旧的缓存代码生效
- 将Observer的生命周期所有者改为
getViewLifecycleOwner(),该生命周期和Fragment的视图生命周期绑定,Fragment视图销毁时会自动移除Observer,不会再收到后续回调 - (可选兜底)在
onChanged回调中增加binding非空判断,避免极端场景下的空指针
修正后的FirstFragment核心代码
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 这里获取Activity级别的ViewModel逻辑是正确的,不用改,推荐用requireActivity避免隐式空指针 mainActivityViewModel = new ViewModelProvider(requireActivity()).get(MainActivityViewModel.class); // 改用viewLifecycleOwner作为生命周期所有者 mainActivityViewModel.getVideos().observe(getViewLifecycleOwner(), new Observer<String>() { @Override public void onChanged(String s) { // 增加非空判断兜底 if (binding != null && binding.testTextView != null) { binding.testTextView.setText(s); } } }); }
额外注意事项
- 后续Fragment中观察和视图渲染相关的LiveData,一律使用
getViewLifecycleOwner(),只有和Fragment实例生命周期绑定的非视图逻辑才用this作为LifecycleOwner - 尽量使用
requireActivity()/requireContext()代替getActivity()/getContext(),避免隐式的空指针问题
内容的提问来源于stack exchange,提问作者mdaabis
相关产品推荐
相关产品推荐

