gpt4 book ai didi

java - Dagger 2 : no injector factory bound for fragment

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:27:04 24 4
gpt4 key购买 nike

我正在尝试将我正在构建的项目转换为将 dagger-android API 用于 DI 框架,但在尝试使用 @ContributesAnroidInjector 注入(inject) fragment 时,我遇到了 IllegalArgumentException 的死胡同。

相关模块和组件如下:

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

我的ActivityBindingModule.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();
}

MainActivityModule.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 可能包含大量 fragment ,并在尝试使用以下 fragment 注入(inject)其中一个 fragment 时导致崩溃:

HomeFragment.java

public class HomeFragment extends Fragment {
....
@Override
public void onAttach(Context context) {
AndroidSupportInjection.inject(this);
super.onAttach(context);
}
....
}

这是我对这次崩溃的 logcat:

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 的绑定(bind)移动到 ActivityBindingModule,应用程序运行良好,但如果我将这些绑定(bind)带回 MainActivityModule,崩溃又回来了。我在这里做错了什么?

编辑:

public class MyApp extends DaggerApplication {

@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerApplicationComponent.builder().application(this).build();
}
}

和我的主要 Activity :

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
}

最佳答案

当您从 HomeFragment 使用 AndroidSupportInjection.inject(this) 进行注入(inject)时,Dagger 将遍历父 fragment 层次结构以找到实现了 HasSupportFragmentInjector 。要使其正常工作,请让您的 MainActivity 扩展 DaggerAppCompatActivity,它实现了 HasSupportFragmentInjector

来自 AndroidSupportInjection.inject(Fragment fragment) 的文档:

Injects {@code fragment} if an associated {@link dagger.android.AndroidInjector} implementation can be found, otherwise throws an {@link IllegalArgumentException}.

Uses the following algorithm to find the appropriate {@code AndroidInjector} to use to inject {@code fragment}:

  1. Walks the parent-fragment hierarchy to find the a fragment that implements {@link HasSupportFragmentInjector}, and if none do
  2. Uses the {@code fragment}'s {@link Fragment#getActivity() activity} if it implements {@link HasSupportFragmentInjector}, and if not
  3. Uses the {@link android.app.Application} if it implements {@link HasSupportFragmentInjector}.

If none of them implement {@link HasSupportFragmentInjector}, a {@link IllegalArgumentException} is thrown.

@throws IllegalArgumentException if no parent fragment, activity, or application implements {@link HasSupportFragmentInjector}.

有了这个,Dagger 将使用

@FragmentScope
@ContributesAndroidInjector
abstract HomeFragment provideHomeFragment();

从您的 MainActivityModule 注入(inject)您的 HomeFragment

关于java - Dagger 2 : no injector factory bound for fragment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48872985/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com