Android ViewModel 的 Hilt 范围限于 Navgraph,Provider Factory 问题
Android Hilt with ViewModel scoped to Navgraph, Provider Factory issue
我正在使用 Hilt 进行 依赖注入 ,专门用于注入 ViewModel。
还想将 ViewModel 范围扩展到 NavGraph。为此,通过传递 NavGraph 获得 ViewModelStoreOwner,现在通过传递 [=] 创建 ViewModel 29=]将 navgraph 提供的实例存储到 ViewModelProvider。我面临的问题是,因为我只传递 store 实例 来获取 ViewModelProvider 而没有任何 Factory,因为 Hilt 将实现它,我收到构建错误 没有零参数构造函数 。当看到源代码时,我发现因为我只提供 store instance 作为参数而没有工厂,自动提供了一个简单的工厂由于 提供的工厂没有参数,因此出现此错误。
如何解决?
正在从源调用的方法 (ViewModelProvider.java)-
* Creates {@code ViewModelProvider}. This will create {@code ViewModels}
* and retain them in a store of the given {@code ViewModelStoreOwner}.
* <p>
* This method will use the
* {@link HasDefaultViewModelProviderFactory#getDefaultViewModelProviderFactory() default factory}
* if the owner implements {@link HasDefaultViewModelProviderFactory}. Otherwise, a
* {@link NewInstanceFactory} will be used.
*/
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
我的 ViewModel Class 需要依赖注入-
private Repository repository;
private MutableLiveData<FeatureCollection> featureCollection = new MutableLiveData<>();
private MutableLiveData<Boolean> loading = new MutableLiveData<>();
private Disposable disposable;
@ViewModelInject
public QuakeListViewModel(Repository repository) {
this.repository = repository;
}
我的片段class-
private FragmentQuakeListBinding _binding;
private QuakeListViewModel _viewModel;
private ViewModelStoreOwner viewModelStoreOwner;
private NavController _navController;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_navController = NavHostFragment.findNavController(this);
viewModelStoreOwner = _navController.getViewModelStoreOwner(R.id.main_nav_graph);
}
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//other implementation
_viewModel = new ViewModelProvider(viewModelStoreOwner).get(QuakeListViewModel.class);
//return binding.root
}
任何帮助将不胜感激
谢谢
根据 Integration with the Jetpack navigation library documentation:
If your ViewModel is scoped to the navigation graph, use the defaultViewModelProviderFactory
object that is available to activities and fragments that are annotated with @AndroidEntryPoint
.
所以你可以使用:
_viewModel = new ViewModelProvider(viewModelStoreOwner,
getDefaultViewModelProviderFactory()).get(QuakeListViewModel.class);
我正在使用 Hilt 进行 依赖注入 ,专门用于注入 ViewModel。 还想将 ViewModel 范围扩展到 NavGraph。为此,通过传递 NavGraph 获得 ViewModelStoreOwner,现在通过传递 [=] 创建 ViewModel 29=]将 navgraph 提供的实例存储到 ViewModelProvider。我面临的问题是,因为我只传递 store 实例 来获取 ViewModelProvider 而没有任何 Factory,因为 Hilt 将实现它,我收到构建错误 没有零参数构造函数 。当看到源代码时,我发现因为我只提供 store instance 作为参数而没有工厂,自动提供了一个简单的工厂由于 提供的工厂没有参数,因此出现此错误。
如何解决?
正在从源调用的方法 (ViewModelProvider.java)-
* Creates {@code ViewModelProvider}. This will create {@code ViewModels}
* and retain them in a store of the given {@code ViewModelStoreOwner}.
* <p>
* This method will use the
* {@link HasDefaultViewModelProviderFactory#getDefaultViewModelProviderFactory() default factory}
* if the owner implements {@link HasDefaultViewModelProviderFactory}. Otherwise, a
* {@link NewInstanceFactory} will be used.
*/
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
我的 ViewModel Class 需要依赖注入-
private Repository repository;
private MutableLiveData<FeatureCollection> featureCollection = new MutableLiveData<>();
private MutableLiveData<Boolean> loading = new MutableLiveData<>();
private Disposable disposable;
@ViewModelInject
public QuakeListViewModel(Repository repository) {
this.repository = repository;
}
我的片段class-
private FragmentQuakeListBinding _binding;
private QuakeListViewModel _viewModel;
private ViewModelStoreOwner viewModelStoreOwner;
private NavController _navController;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_navController = NavHostFragment.findNavController(this);
viewModelStoreOwner = _navController.getViewModelStoreOwner(R.id.main_nav_graph);
}
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//other implementation
_viewModel = new ViewModelProvider(viewModelStoreOwner).get(QuakeListViewModel.class);
//return binding.root
}
任何帮助将不胜感激
谢谢
根据 Integration with the Jetpack navigation library documentation:
If your ViewModel is scoped to the navigation graph, use the
defaultViewModelProviderFactory
object that is available to activities and fragments that are annotated with@AndroidEntryPoint
.
所以你可以使用:
_viewModel = new ViewModelProvider(viewModelStoreOwner,
getDefaultViewModelProviderFactory()).get(QuakeListViewModel.class);