我已阅读以下文章,但我不知道自己在做什么错。
Dagger AndroidInjector cannot be provided without an @Provides-annotated method
<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. . .
}
任何建议将不胜感激。