我使用的是dagger.android,想注入ViewModels。另一方面,我有一个ApiModule
,它取决于活动上下文,
这里是AppComponent
@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class,
ActivityBindingModule.class,
ViewModelModule.class
})
public interface AppComponent extends AndroidInjector<MyApp> {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder<MyApp> {}
}
ViewModelModule
提供了ViewModelProvider.Factory
@Module
abstract class ViewModelModule {
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(MyAppViewModelFactory factory);
}
这里是ActivityBindingModule
:
@Module
abstract class ActivityBindingModule {
//MainActivity
@ActivityScoped
@ContributesAndroidInjector(modules = {
MainActivityModule.class,
ApiModule.class
})
abstract MainActivity contributeMainActivityInjector();
@Module
abstract class MainActivityModule {
@ActivityScoped
@Binds
abstract Activity bindMainActivity(MainActivity activity);
@Binds
@IntoMap
@ViewModelKey(UserViewModel.class)
abstract ViewModel bindUserViewModel(UserViewModel userViewModel);
}
//SecondActivity
@ActivityScoped
@ContributesAndroidInjector(modules = {
SecondActivityModule.class,
ApiModule.class
})
abstract SecondActivity contributeSecondActivityInjector();
@Module
abstract class SecondActivityModule {
@ActivityScoped
@Binds
abstract Activity bindSecondActivity(SecondActivity activity);
@Binds
@IntoMap
@ViewModelKey(DetailViewModel.class)
abstract ViewModel bindDetailViewModel(DetailViewModel detailViewModel);
}
}
我有以下注入层次结构:
MainActivity --inject--> ViewModelProvider.Factory --inject--> MyAppViewModelFactory --inject--> UserViewModel --inject--> UserRepository --inject--> ApiService --inject--> Activity context
SecondActivity --inject--> ViewModelProvider.Factory --inject--> MyAppViewModelFactory --inject--> DetailViewModel --inject--> DetailRepository --inject--> ApiService --inject--> Activity context
我们提供:
Activity
(和MainActivityModule
)上的SecondActivityModule
上下文ApiService
上的ApiModule
(已添加到ActivityBindingModule
上每个活动的模块中)UserRepository
和DetailRepository
是@Singleton
UserViewModel
和MainActivityModule
上的DetailViewModel
SecondActivityModule
是@Singleton 这里是MyAppViewModelFactory
:
MyAppViewModelFactory
我收到此错误:
@Singleton
public class MyAppViewModelFactoryimplements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
MyAppViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
this.creators = creators;
}
@SuppressWarnings("unchecked")
@Override
@NonNull
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
Provider<? extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
我尝试将error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at
com.example.viewmodels.MyAppViewModelFactory.<init>(creators)
com.example.viewmodels.MyAppViewModelFactory is injected at
com.example.di.ViewModelModule.bindViewModelFactory(factory)
android.arch.lifecycle.ViewModelProvider.Factory is injected at
com.example.activities.MainActivity.viewModelFactory
com.example.activities.MainActivity is injected at
dagger.android.AndroidInjector.inject(T)
component path: com.example.di.AppComponent ? com.example.di.ActivityBindingModule_ContributeMainActivityInjector.MainActivitySubcomponent
(从bindUserViewModel
)和MainActivityModule
(从bindDetailViewModel
)移到SecondActivityModule
,但出现此错误:
ViewModelModule
我在这里想念什么? iosched项目可以毫无问题地完成同样的事情
答案 0 :(得分:0)
首先,您需要在“应用程序”和“活动”级别重构Dagger2设置。
其次,您的ViewModelProviderFactory
类有点复杂。现在,我将为您重组代码。
应用程序级别
AppComponent
@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class,
ActivityBindingModule.class
})
public interface AppComponent extends AndroidInjector<MyApp> {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder<MyApp> {}
}
ActivityBindingModule
@Module
abstract class ActivityBindingModule {
@ContributesAndroidInjector(modules = MainActivityModule.class)
abstract MainActivity contributeMainActivity();
//This goes for other activities
}
AppModule
此类仅提供常见的类,并且可以在
整个应用程序中的任何活动。
@Module
class AppModule {
@Singleton
@Provides
//Your ApiService interface comes here
//Retrofit
//Database
}
App
类应简化DaggerApplication。这会自动注入其成员
class MyApp extends DaggerApplication
@Override
public void onCreate() {
super.onCreate();
}
@Override
protected AndroidInjector<? extends DaggerApplication>
applicationInjector() {
return DaggerHorizonMainComponent.builder().create(this);
}
活动级别
MainActivityModule
这是您拥有ViewModel
和ViewModelProviderFactory
@Module
class MainACtivityModule {
@Provides
MainActivityViewModel provideMainActivityViewModel(){
return new MainActivityViewModel();
}
@Provides
ViewModelProvider.Factory provideViewModelProvider(MainActivityViewModel
viewModel){
return new ViewModelProviderFactory<>(viewModel);
}
//Your repository comes here too
}
ViewModel
类
class MyViewModel extends ViewModel {
@Inject
public MyViewModel(){
}
}
ViewModelProviderFactory
只需复制此代码
public class ViewModelProviderFactory<V> implements
ViewModelProvider.Factory {
private V viewModel;
public ViewModelProviderFactory(V viewModel) {
this.viewModel = viewModel;
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
if (modelClass.isAssignableFrom(viewModel.getClass())) {
return (T) viewModel;
}
throw new IllegalArgumentException("Unknown class name");
}
}
最后,在您的MainActivity
类中,注入ViewModelProviderFactory。您无需在此处注入Dagger,因为您可以将其扩展到DaggerAppCompatActivity
public class Mainactivity extends DaggerAppCompatActivity{
@Inject
ViewModelProvider.Factory factory;
private MyViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//You set your view here
viewmodel =
ViewModelProviders.of(this,factory).get(MyViewModel.class);
}
}
答案 1 :(得分:0)
所有设置听起来正确。 主要原因是未提供ApiService
。
错误:[Dagger / MissingBinding] [dagger.android.AndroidInjector.inject(T)] 如果没有以下提示,则无法提供tk.medlynk.medlynk.http.ApiService: @提供注释的方法。
要解决此问题,您只需在某个模块中提供它即可。
class AppModule {
@Singleton
@Provides
fun provideApiService(): ApiService {
....
}
}