错误:[Dagger / MissingBinding]如果没有@Provides注释的方法,就无法提供androidx.lifecycle.ViewModelProvider.Factory

时间:2019-06-06 11:47:49

标签: android dagger-2 android-lifecycle android-intentservice

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

  1. Dagger AndroidInjector cannot be provided without an @Provides-annotated method

  2. <android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method

堆栈跟踪

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

Module#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 . . . 
    }
}

AppModule

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

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

AppComponent

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

   . . . Other Activity Injectors. . . 
}

任何建议将不胜感激。

0 个答案:

没有答案