Android Hilt 的 ViewModel 范围仅限于 Navgraph、Provider Factory 问题

Deb*_*jee 5 android dependency-injection android-jetpack dagger-hilt

我使用Hilt进行依赖注入,专门用于注入ViewModel。还想将ViewModel 范围限制为 NavGraph。为此,我们通过传递NavGraph来获取ViewModelStoreOwner,现在通过将导航图提供的存储实例传递给ViewModelProvider来创建ViewModel。我面临的问题是,因为我只传递store 实例来获取ViewModelProvider而没有任何Factory,因为Hilt将实现它,所以我收到构建错误has no Zero argument constructor。当看到源代码时,我发现由于我只提供存储实例作为参数而不提供工厂,因此会自动提供一个简单的工厂,并且由于提供的工厂没有参数,因此出现此错误。

怎么解决这个问题呢?

从源代码(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());
    }
Run Code Online (Sandbox Code Playgroud)

我的 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;
    }
Run Code Online (Sandbox Code Playgroud)

我的片段类-

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

    }
Run Code Online (Sandbox Code Playgroud)
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        //other implementation
        _viewModel = new ViewModelProvider(viewModelStoreOwner).get(QuakeListViewModel.class);
        //return binding.root
    }
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激

谢谢

ian*_*ake 4

根据与 Jetpack 导航库集成文档

如果您的 ViewModel 的范围仅限于导航图,请使用defaultViewModelProviderFactory可用于注释的活动和片段的对象@AndroidEntryPoint

所以你可以使用:

_viewModel = new ViewModelProvider(viewModelStoreOwner,
    getDefaultViewModelProviderFactory()).get(QuakeListViewModel.class);
Run Code Online (Sandbox Code Playgroud)

  • 如果我们使用 hilt 进行 DI,它是否会更改为 `hiltNavGraphViewModels`? (5认同)
  • @Nabeel你必须实现使用“hiltNavGraphViewModels”的依赖关系,即“实现'androidx.hilt:hilt-navigation-fragment:1.0.0'” (2认同)