我正在尝试使用片段创建应用程序。我创建了一个测试片段(HomeFragment),它只有一个简单的TextView。我创建了所有必需的类(模块,模型和提供者)。但我得到了一个奇怪的并发症错误
Error:(25, 10) error: [dagger.android.AndroidInjector.inject(T)] android.arch.lifecycle.ViewModelProvider.Factory is bound multiple times:
@Provides android.arch.lifecycle.ViewModelProvider.Factory app.series.com.series3go.ui.main.MainActivityModule.mainViewModelProvider(app.series.com.series3go.ui.main.MainViewModel)
@Provides android.arch.lifecycle.ViewModelProvider.Factory app.series.com.series3go.ui.home.HomeFragmentModule.provideHomeFragmentViewModel(app.series.com.series3go.ui.home.HomeFragmentViewModel)
HomeFragment
public class HomeFragment extends BaseFragment<HomeFragmentBinding, HomeFragmentViewModel> {
public static final String TAG = HomeFragment.class.getSimpleName();
@Inject
ViewModelProvider.Factory mViewModelFactory;
HomeFragmentBinding mHomeFragmentBinding;
private HomeFragmentViewModel mHomeFragmentViewModel;
public static HomeFragment newInstance() {
Bundle args = new Bundle();
HomeFragment fragment = new HomeFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mHomeFragmentBinding = getViewDataBinding();
setUp();
subscribeToLiveData();
}
@Override
public HomeFragmentViewModel getViewModel() {
mHomeFragmentViewModel = ViewModelProviders.of(this, mViewModelFactory).get(HomeFragmentViewModel.class);
return mHomeFragmentViewModel;
}
@Override
public int getBindingVariable() {
return BR.viewModel;
}
@Override
public int getLayoutId() {
return R.layout.home_fragment;
}
private void setUp() {
}
private void subscribeToLiveData() {
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
}
HomeFragmentModule
@Module
public class HomeFragmentModule
{
@Provides
HomeFragmentViewModel homeFragmentViewModel()
{
return new HomeFragmentViewModel();
}
@Provides
ViewModelProvider.Factory provideHomeFragmentViewModel(HomeFragmentViewModel homeFragmentViewModel)
{
return new ViewModelProviderFactory<>(homeFragmentViewModel);
}
}
HomeFragmentProvider
@Module
public abstract class HomeFragmentProvider {
@ContributesAndroidInjector(modules = HomeFragmentModule.class)
abstract HomeFragment provideHomeFragmentFactory();
}
HomeFragmentViewModel
public class HomeFragmentViewModel扩展了BaseViewModel {
private final ObservableField<String> appVersion = new ObservableField<>();
public HomeFragmentViewModel() {
super();
appVersion.set("123");
}
public ObservableField<String> getAppVersion() {
return appVersion;
}
}
home_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="app.series.com.series3go.ui.main.MainActivity">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="app.series.com.series3go.ui.home.HomeFragmentViewModel" />
</data>
<TextView
android:id="@+id/tvAppVersion"
style="@style/TextStyle.Title.Sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:padding="5dp"
android:text="@{viewModel.appVersion}" />
</layout>
是否有关于提供程序类(HomeFragmentProvider)中函数名的命名约定, 我没有看到在项目的任何地方使用这些功能。它们是否用在生成的匕首类中?
由于
更新
AppComponent
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, AppModule.class, ActivityBuilder.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
void inject(SeriesApp app);
}
答案 0 :(得分:9)
您的依赖关系图中有两个提供ViewModelProvider.Factory
的方法。
要解决这种歧义,请使用@Named
注释。
@Module
public class HomeFragmentModule {
@Provides
@Named("HomeFragment")
ViewModelProvider.Factory provideHomeFragmentViewModel(HomeFragmentViewModel homeFragmentViewModel) {
return new ViewModelProviderFactory<>(homeFragmentViewModel);
}
/* Rest of the code */
}
public class HomeFragment {
@Inject
@Named("HomeFragment")
ViewModelProvider.Factory mViewModelFactory;
/* Rest of the code */
}
您也应该对第二个ViewModelProvider.Factory
执行相同操作(在MainActivity
及其模块中)。
答案 1 :(得分:0)
我将编辑错误日志,以使其更容易理解:
错误:ViewModelProvider.Factory多次绑定:
@Provides ViewModelProvider.Factory MainActivityModule.mainViewModelProvider(MainViewModel)
@Provides ViewModelProvider.Factory HomeFragmentModule.provideHomeFragmentViewModel(HomeFragmentViewModel)
您已在HomeFragment
内声明,您愿意注入ViewModelProvider.Factory
。 Dagger试图找到一个提供者方法并找到其中两个:一个来自MainActivityModule
,另一个来自HomeFragmentModule
。所以,匕首会混淆并中止编译。
我建议您采用类似于Google展示GithubBrowserSample
应用中的方法。使用ViewModels
注释将该应用Map<Class, ViewModel>
are being injected放入地图(@IntoMap
)中。在你的情况下,你会将ViewModelProvider.Factory
- ies注入地图。
您可以在GithubViewModelFactory
内看到地图的注入。
或者,您可以考虑@ dev.bmax建议的approach。