ViewModel获取Application实例为null,无法获取依赖问题求助
问题解决:ViewModel中APPLICATION_KEY获取返回null
原因分析
当在Fragment中以this作为ViewModelStoreOwner创建ViewModelProvider时,默认的CreationExtras中并没有携带APPLICATION_KEY,导致你通过creationExtras.get(APPLICATION_KEY)无法获取到Application实例。
解决方案
方案一:手动传递Application到CreationExtras
在Fragment中创建ViewModel时,手动构建包含APPLICATION_KEY的CreationExtras:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Application app = requireActivity().getApplication(); // 创建包含APPLICATION_KEY的Extras CreationExtras extras = new CreationExtras(ViewModelProvider.DefaultCreationExtras.from(requireContext())); extras.set(ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY, app); MainFragmentVM myViewModel = new ViewModelProvider( this, ViewModelProvider.Factory.from(MainFragmentVM.initializer), extras ).get(MainFragmentVM.class); }
方案二:改用AndroidViewModel简化依赖注入
AndroidViewModel是ViewModel的子类,专门用于接收Application实例,其默认Factory会自动注入Application,无需手动处理CreationExtras:
- 修改ViewModel继承AndroidViewModel:
public class MainFragmentVM extends AndroidViewModel { DBHelper dbHelper; public MainFragmentVM(@NonNull Application app) { super(app); // 转换为自定义MyApp实例获取DBHelper MyApp myApp = (MyApp) app; this.dbHelper = myApp.getDbHelper(); } }
- 在Fragment中直接获取ViewModel:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); MainFragmentVM myViewModel = new ViewModelProvider(this).get(MainFragmentVM.class); }
方案三:绑定ViewModel到Activity生命周期(按需选择)
如果你的ViewModel需要和Activity生命周期绑定,而非Fragment,可以将ViewModelStoreOwner改为requireActivity(),此时默认CreationExtras会包含APPLICATION_KEY:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); MainFragmentVM myViewModel = new ViewModelProvider( requireActivity(), ViewModelProvider.Factory.from(MainFragmentVM.initializer) ).get(MainFragmentVM.class); }
额外检查
确保你已经在AndroidManifest.xml中注册了自定义的MyApp类,否则无法获取到自定义Application实例:
<application android:name=".MyApp" ...> ... </application>
内容的提问来源于stack exchange,提问作者Vadym Melnychenko
相关产品推荐
相关产品推荐

