【问题标题】:Android Hilt with ViewModel scoped to Navgraph, Provider Factory issue带有 ViewModel 的 Android Hilt 范围为 Navgraph,Provider Factory 问题
【发布时间】:2020-10-12 17:09:03
【问题描述】:

我将 Hilt 用于 依赖注入,专门用于注入 ViewModel。 还想将 ViewModel 限定为 NavGraph。为此,通过传递 NavGraph 获得 ViewModelStoreOwner,现在通过传递由导航图提供的 store 实例 创建 ViewModel strong> 到 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 类-

    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;
    }

我的片段类-

    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
    }

任何帮助将不胜感激

谢谢

【问题讨论】:

    标签: android dependency-injection android-jetpack dagger-hilt


    【解决方案1】:

    根据Integration with the Jetpack navigation library documentation

    如果您的 ViewModel 是scoped to the navigation graph,请使用defaultViewModelProviderFactory 对象,该对象可用于带有@AndroidEntryPoint 注释的活动和片段。

    所以你可以使用:

    _viewModel = new ViewModelProvider(viewModelStoreOwner,
        getDefaultViewModelProviderFactory()).get(QuakeListViewModel.class);
    

    【讨论】:

    • 如果我们为 DI 使用 hilt 是否更改为 hiltNavGraphViewModels
    • @nabeel - 是的,该 API 是一个方便的包装器,可以为您执行此调用。
    猜你喜欢
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 2021-09-24
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多