匕首2:没有喷油器工厂绑定碎片
我正在尝试将我正在构建的项目转换为使用DI框架的dagger-android API,但是当尝试使用@ContributesAnroidInjector注入片段时,我遇到了非法ArgumentException的死胡同。
相关模块和组件包括在下面:
应用程序组件.java
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class,
ApplicationModule.class,
ActivityBindingModule.class,
DataManagerModule.class})
public interface ApplicationComponent extends AndroidInjector<MyApplication> {
DataManagerContract getDataManager();
void inject(MyApplication application);
@Component.Builder
interface Builder {
@BindsInstance
ApplicationComponent.Builder application(Application application);
ApplicationComponent build();
}
}
我的活动绑定模块.java:
@Module
public abstract class ActivityBindingModule {
@ActivityScope
@ContributesAndroidInjector(modules = MainActivityModule.class)
abstract MainActivity bindMainActivity();
@ActivityScope
@ContributesAndroidInjector(modules = SplashActivityModule.class)
abstract SplashActivity bindSplashActivity();
@ActivityScope
@ContributesAndroidInjector(modules = LoginActivityModule.class)
abstract LoginActivity bindLoginActivity();
}
主要活动模块.java
@Module
public abstract class MainActivityModule {
@ActivityScope
@Binds
abstract MainActivityContract.Presenter provideMainActivityPresenter(MainActivityPresenter presenter);
@FragmentScope
@ContributesAndroidInjector
abstract HomeFragment provideHomeFragment();
@FragmentScope
@Binds
abstract HomeFragmentContract.Presenter provideHomeFragmentPresenter(HomeFragmentPresenter presenter);
// Inject other fragments and presenters
}
SplashActivity 和 LoginActivity 仅取决于它们各自的演示者,而 dagger 在这些演示者中工作正常。但是我的 MainActivity 可能包含许多片段,并且在尝试使用以下方法注入其中一个片段时会导致崩溃:
家庭碎屑.java
public class HomeFragment extends Fragment {
....
@Override
public void onAttach(Context context) {
AndroidSupportInjection.inject(this);
super.onAttach(context);
}
....
}
这是我对这次崩溃的日志:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp/com.myapp.main.MainActivity}: java.lang.IllegalArgumentException: No injector factory bound for Class<com.myapp.ui.main.Home.HomeFragment>
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.IllegalArgumentException: No injector factory bound for Class<com.myapp.ui.main.Home.HomeFragment>
at dagger.android.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:104)
at dagger.android.support.AndroidSupportInjection.inject(AndroidSupportInjection.java:74)
at com.myapp.ui.main.Home.HomeFragment.onAttach(HomeFragment.java:65)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1363)
at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1109)
at android.support.v4.app.FragmentTransition.calculateFragments(FragmentTransition.java:996)
at android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:99)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2364)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3221)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3171)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:192)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:560)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
at android.app.Activity.performStart(Activity.java:6696)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2628)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
我不确定代码中的问题在哪里。如果我将HomeFragment的绑定移动到ActiveBindingModule,应用程序运行良好,但是如果我将这些绑定带回MainActivityModule,崩溃就会回来。我在这里做错了什么?
编辑:
public class MyApp extends DaggerApplication {
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerApplicationComponent.builder().application(this).build();
}
}
和我的主要活动:
public class MainActivity extends AppCompatActivity
implements MainActivityContract.View,
NavigationView.OnNavigationItemSelectedListener {
@Inject
MainActivityContract.Presenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Open home fragment on first start
if (savedInstanceState == null) {
// Create new instance of HomeFragment
HomeFragment homeFragment = HomeFragment.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_main, homeFragment)
.commit();
}
// Other logic
}