首页 > 解决方案 > 错误:[Dagger/MissingBinding] androidx.lifecycle.ViewModelProvider.Factory 不能在没有@Provides-annotated 方法的情况下提供

问题描述

我已阅读以下文章,但我不知道我做错了什么。

  1. 没有@Provides-annotated 方法就不能提供 Dagger AndroidInjector

  2. <android.arch.lifecycle.ViewModel>> 不能在没有@Provides-annotated 方法的情况下提供

堆栈跟踪

error: [Dagger/MissingBinding] androidx.lifecycle.ViewModelProvider.Factory cannot be provided without an @Provides-annotated method.
A binding with matching key exists in component: com.mycompany.mobile.dagger.AppModule_ContributeSettingsActivityInjector.SettingsActivitySubcomponent
A binding with matching key exists in component: com.mycompany.mobile.settings.dagger.SettingsActivityModule_ContributeSignInPreferencesFragment.AuthenticationPreferencesFragmentSubcomponent
androidx.lifecycle.ViewModelProvider.Factory is injected at
com.mycompany.mobile.notifications.PushJobIntentService.viewModelProviderFactory
com.mycompany.mobile.notifications.PushJobIntentService is injected at
dagger.android.AndroidInjector.inject(T) [com.mycompany.mobile.dagger.AppComponent → com.mycompany.mobile.dagger.AppModule_ContributePushJobIntentServiceInjector.PushJobIntentServiceSubcomponent]

ViewModelProvider.Factory 实现

public class InjectableViewModelProviderFactory implements ViewModelProvider.Factory
{
    private final Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModelMap;

    @Inject
    InjectableViewModelProviderFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModelMap)
    {
        this.viewModelMap = viewModelMap;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass)
    {
        final Provider<ViewModel> viewModelProvider = viewModelMap.get(modelClass);
        if (viewModelProvider != null)
        {
            final ViewModel viewModel = viewModelProvider.get();
            if (modelClass.isInstance(viewModel))
            {
                final T viewModelAsModelClass = modelClass.cast(viewModel);
                if (viewModelAsModelClass != null)
                    return viewModelAsModelClass;
            }
        }
        throw new IllegalStateException(String.format("Could not find view model provider for %1$s",
            modelClass.getSimpleName()));
    }
}

模块#1

@Module
public abstract class ViewModelInjectionModule
{
    @Binds
    abstract ViewModelProvider.Factory bindViewModelProviderFactory(InjectableViewModelProviderFactory factory);

    @Multibinds
    abstract Map<Class<? extends ViewModel>, ViewModel> provideViewModelProviderMap();
}

模块#2

有多个这样的模块将密钥注入其他模块。

@Module(includes=ViewModelInjectionModule.class)
public abstract SettingsModule {

@Binds
    @IntoMap
    @ViewModelKey(NotificationsViewModel.class)
    abstract ViewModel bindNotificationsViewModel(NotificationsViewModel viewModel);

    @Binds
    @IntoMap
    @ViewModelKey(DcsViewModel.class)
    abstract ViewModel bindDcsViewModel(DcsViewModel viewModel);
}

ViewModel.Factory 实例被注入到 IntentService 的一个实例中。

public class PushJobIntentService extends IntentService
{

    @Inject
    ViewModelProvider.Factory viewModelProviderFactory;

    @Override
    protected void onHandleWork(@NonNull Intent intent)
    {

        ... Run an intent service . . . 
    }
}

应用模块

@Module(includes = {
    AnalyticsAppModule.class,
    AppUpgradeModule.class,
    AndroidSupportInjectionModule.class,
    AppDcsModule.class
})
public abstract class AppModule
{

    @ActivityScope
    @ContributesAndroidInjector(modules = {SettingsModule.class})
    abstract SettingsActivity contributeSettingsActivityInjector();
}

应用组件

@Singleton
@Component(
    modules = {
        AppModule.class,
        .. . Other modules
    })
public interface AppComponent {
    @NonNull
DispatchingAndroidInjector<Activity> getDispatchingActivityInjector();

   . . . Other Activity Injectors. . . 
}

任何建议将不胜感激。

标签: androiddagger-2android-lifecycleandroid-intentservice

解决方案


推荐阅读