热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何使用dagger.android@Inject成员在BaseActivity中?

如何解决《如何使用dagger.android@Inject成员在BaseActivity中?》经验,为你挑选了1个好方法。

这是我的情况:

我希望所有活动都可以继承 BaseActivity

在中BaseActivity,我要注入Navigator(它有助于我管理Fragments后退栈并在活动之间进行导航):

abstract class BaseActivity : DaggerAppCompatActivity() {
    @Inject
    lateinit var navigator: Navigator

    @Inject
    lateinit var prefs: SharedPreferences // injected via AppModule.kt, see below.
}

Navigator类需要FragmentManager在其构造函数:

class Navigator @Inject constructor(
    val fragmentManager: FragmentManager) {
    // class body
}

我想从中提供FragmentManager一个BaseActivity对象BaseActivityModule

@Module
class BaseActivityModule {
    @PerActivity
    @Provides
    fun provideFragmentManager(baseActivity: BaseActivity): FragmentManager {
        return baseActivity.supportFragmentManager
    }
}

这是我其余的组件和模块:

AppComponent.kt

@Singleton @Component(modules = [
    AndroidSupportInjectionModule::class,
    AppModule::class,
    ActivityBindingModule::class])
interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder
        fun build(): AppComponent
    }
    fun inject(app: AndroidApplication)
}

AppModule.kt

@Module
class AppModule {
    @Singleton
    @Provides
    fun providesPrefs(application: Application): SharedPreferences {
        return application.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)
    }
}

ActivityBindingModule.kt

@Module
abstract class ActivityBindingModule {
    @ContributesAndroidInjector
    abstract fun bindMainActivity(): MainActivity

    @ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
    abstract fun bindBaseActivity(): BaseActivity
}

BaseActivityModule.kt

@Module
class BaseActivityModule {
    @Provides
    fun provideFragmentManager(baseActivity: BaseActivity): FragmentManager {
        return baseActivity.supportFragmentManager
    }
}

这是编译错误消息:

Error: [dagger.android.AndroidInjector.inject(T)]
android.support.v4.app.FragmentManager cannot be provided
without an @Provides- or @Produces-annotated method.

Error:A binding with matching key exists in component:
com.myapp.ActivityBindingModule_BindBaseActivity.BaseActivitySubcomponent

David Medenj.. 7

问题在于您的假设,即您需要BaseActivity在某个时候注入a 。

@Module
abstract class ActivityBindingModule {
  @ContributesAndroidInjector
  abstract fun bindMainActivity(): MainActivity


  // ...that's not really how it works... :/
  @ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
  abstract fun bindBaseActivity(): BaseActivity
}

使用上面的代码,您最终要注入MainActivity一些组件BaseActivity,而要注入一些组件,但是都不能“注入”两者。您收到的错误是因为MainActivity无法提供FragmentManager它需要注入其父级中的错误BaseActivity。它缺少这样做的模块。您只能将添加BaseActivityModule到MainActivityComponent实际上无法访问的其他组件中,因此无法提供错误。

匕首始终需要注入整个对象。没有部分注入,也没有一次从多个组件注入。如果单个组件不能提供它需要的所有依赖关系,则会出现错误。您fun bindBaseActivity(): BaseActivity是无用的,因为您将永远不会使用BaseActivity,而只会使用MainActivity它的或其他子类。这些组件还必须能够提供BaseActivity的依赖项。


如果要在BaseActivity中注入依赖项,则需要添加一个提供必要绑定的模块。您的代码最终应如下所示:

@Module
abstract class ActivityBindingModule {
  @ContributesAndroidInjector(modules = [BaseActivityModule::class, MainActivityModule::class])
  abstract fun bindMainActivity(): MainActivity

  // no BaseActivity component necessary
}

@Module
abstract class MainActivityModule {
  @Binds
  abstract fun bindBaseActivity(activity: MainActivity) : BaseActivity
}

这将执行以下操作:

    它添加BaseActivityModule到MainActivityComponent中,因此您的基本依赖关系可以由该组件提供并MainActivity可以注入

    MainActivity以您的身份绑定到另一个模块中,BaseActivity因此您可以在模块中使用它,而不必为每个活动都绑定一个FragmentManager

尽管您可以重用BaseActivityModule并将其添加到所有活动实现中,但是您将必须添加一个模块以将活动绑定BaseActivity为每个活动中的一个。

可能有一种更优化的方法,但这就是注入子类的基本要求。



1> David Medenj..:

问题在于您的假设,即您需要BaseActivity在某个时候注入a 。

@Module
abstract class ActivityBindingModule {
  @ContributesAndroidInjector
  abstract fun bindMainActivity(): MainActivity


  // ...that's not really how it works... :/
  @ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
  abstract fun bindBaseActivity(): BaseActivity
}

使用上面的代码,您最终要注入MainActivity一些组件BaseActivity,而要注入一些组件,但是都不能“注入”两者。您收到的错误是因为MainActivity无法提供FragmentManager它需要注入其父级中的错误BaseActivity。它缺少这样做的模块。您只能将添加BaseActivityModule到MainActivityComponent实际上无法访问的其他组件中,因此无法提供错误。

匕首始终需要注入整个对象。没有部分注入,也没有一次从多个组件注入。如果单个组件不能提供它需要的所有依赖关系,则会出现错误。您fun bindBaseActivity(): BaseActivity是无用的,因为您将永远不会使用BaseActivity,而只会使用MainActivity它的或其他子类。这些组件还必须能够提供BaseActivity的依赖项。


如果要在BaseActivity中注入依赖项,则需要添加一个提供必要绑定的模块。您的代码最终应如下所示:

@Module
abstract class ActivityBindingModule {
  @ContributesAndroidInjector(modules = [BaseActivityModule::class, MainActivityModule::class])
  abstract fun bindMainActivity(): MainActivity

  // no BaseActivity component necessary
}

@Module
abstract class MainActivityModule {
  @Binds
  abstract fun bindBaseActivity(activity: MainActivity) : BaseActivity
}

这将执行以下操作:

    它添加BaseActivityModule到MainActivityComponent中,因此您的基本依赖关系可以由该组件提供并MainActivity可以注入

    MainActivity以您的身份绑定到另一个模块中,BaseActivity因此您可以在模块中使用它,而不必为每个活动都绑定一个FragmentManager

尽管您可以重用BaseActivityModule并将其添加到所有活动实现中,但是您将必须添加一个模块以将活动绑定BaseActivity为每个活动中的一个。

可能有一种更优化的方法,但这就是注入子类的基本要求。


推荐阅读
author-avatar
mobiledu2502887783
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有