【问题标题】:Cannot inject a Fragment with Dagger 2无法使用 Dagger 2 注入 Fragment
【发布时间】:2018-10-15 16:01:08
【问题描述】:

我能够注入活动、广播接收器等...,但是当我尝试以相同的方式注入片段时,我得到以下异常:

.../AppComponent.java:8: error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.String,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> cannot be provided without an @Provides-annotated method.
    public abstract interface AppComponent extends dagger.android.AndroidInjector<com.inepex.simpleclient.App> {
                    ^
          java.util.Map<java.lang.String,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> is injected at
              dagger.android.DispatchingAndroidInjector.<init>(…, injectorFactoriesWithStringKeys)
          dagger.android.DispatchingAndroidInjector<android.support.v4.app.Fragment> is injected at
              com.inepex.tracker.SimpleTrackerApp.fragmentInjector
          com.inepex.simpleclient.App is injected at
              dagger.android.AndroidInjector.inject(T)

我遵循了这个描述: https://code.luasoftware.com/tutorials/android/dagger2-injection-for-fragment/

更新

我想要一个 Fragment 实例,因为我想像这样切换 Fragment:

Fragment fragment = new WelcomeFragment();

FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.contentFragment, fragment);
transaction.commit();

注入片段:

class MainActivity : BaseActivity() {

    @Inject
    lateinit var welcomeFragment: WelcomeFragment

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        ButterKnife.bind(this)
    }
}

组件:

@Component(modules = arrayOf(AndroidInjectionModule::class, AppModule::class, AbstractAppModule::class, AbstractLibModule::class, LibModule::class))
@Singleton
interface AppComponent : AndroidInjector<App> {

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: App): Builder

        fun build(): AppComponent
    }
}

模块:

@Module
abstract class AbstractAppModule {

    @ContributesAndroidInjector
    internal abstract fun welcomeFragment(): WelcomeFragment

    @ContributesAndroidInjector
    internal abstract fun mainActivity(): MainActivity

    @ContributesAndroidInjector
    internal abstract fun onboardingActivity(): OnboardingActivity
}

应用:

open class SimpleTrackerApp : MultiDexApplication(),
        HasActivityInjector,
        HasServiceInjector,
        HasBroadcastReceiverInjector,
        HasSupportFragmentInjector {


    @Inject
    lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>

    @Inject
    lateinit var dispatchingServiceInjector: DispatchingAndroidInjector<Service>

    @Inject
    lateinit var dispatchingBroadcastReceiverInjector: DispatchingAndroidInjector<BroadcastReceiver>

    @Inject
    lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>

    override fun activityInjector(): AndroidInjector<Activity> = dispatchingAndroidInjector

    override fun serviceInjector(): AndroidInjector<Service> = dispatchingServiceInjector

    override fun broadcastReceiverInjector(): AndroidInjector<BroadcastReceiver> =
            dispatchingBroadcastReceiverInjector

    override fun supportFragmentInjector(): DispatchingAndroidInjector<Fragment> = fragmentInjector

【问题讨论】:

  • Dagger 找不到您的片段实例的提供者。请发布您的 Dagger 设置以及您将片段实例注入的位置。
  • Hi Ismael,我添加了片段注入相关部分。

标签: android android-fragments dagger-2


【解决方案1】:

更新:

我注意到您使用的是 android.support.v4.app.Fragment,但您使用的是来自应用程序的 Fragment。你需要添加

implementation 'com.google.dagger:dagger-android-support:2.x' // if you use the support libraries

另外,activity需要实现HasFragmentInjector接口

public class YourActivity extends Activity
    implements HasFragmentInjector {
  @Inject DispatchingAndroidInjector<Fragment> fragmentInjector;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    AndroidInjection.inject(this);
    super.onCreate(savedInstanceState);
    // ...
  }

  @Override
  public AndroidInjector<Fragment> fragmentInjector() {
    return fragmentInjector;
  }
}

更新:

首先,您需要在创建之前注入片段

最后,在您的 Activity.onCreate() 方法中,调用 AndroidInjection.inject(this) 之前调用 super.onCreate();:

public class YourActivity extends Activity {
  public void onCreate(Bundle savedInstanceState) {
    AndroidInjection.inject(this);
    super.onCreate(savedInstanceState);
  }
}

Docs

你添加了这个模块吗?

@Module abstract class FragmentModule {
    @ContributesAndroidInjector
    internal abstract fun contributePhotoPinListFragment(): PhotoPinListFragment
}

到应用组件:

@Singleton
@Component(modules = [..., (FragmentModule::class)])
interface AppComponent {

【讨论】:

  • 嗨,Igor,是的,我在模块和组件中有这个。
  • @balint.steinbach 我的意思是,您是否向组件添加了模块。只是仔细检查:)
  • @balint.steinbach 我更新了答案,当看到你的活动时
  • 对不起,我的错误,仍然是同样的问题。是否可以在 Activity 中执行此操作?:@Inject lateinit var welcomeFragment: WelcomeFragment
  • @balint.steinbach 1. 你不需要在活动中注入welcomeFragment。 2.你需要在你的activity中实现HasSupportFragmentInjector
【解决方案2】:

看起来您没有在模块中为 Fragment 添加提供程序。 Dagger 不知道如何找到您尝试注入的 Fragment 的对象。所以在模块类中你必须创建一个提供如下(只是一个例子)

@Provides
@Singleton
fun provideFragment(): Fragment = Fragment()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 2016-08-31
    相关资源
    最近更新 更多