【问题标题】:How to @Inject an abstract BaseActivity and its subclasses using dagger.android?如何使用 dagger.android @Inject 抽象 BaseActivity 及其子类?
【发布时间】:2018-01-30 13:36:30
【问题描述】:

我正在使用来自 Dagger 2 的新 dagger.android 包在我的项目中注入 Android 依赖项。

  • 我需要我的所有活动都是抽象 BaseActivity 的子类
  • 在我的BaseActivity 中,我有要注入的成员变量。这样:

    abstract class BaseActivity : AppCompatActivity() {
        @Inject
        lateinit var prefs: MyPreferenceDataStore
        ...// more @Injected members
    }
    
  • 我这样做是因为我希望BaseActiviy 的子类可以访问BaseActivity 的注入成员:

    class SubClassActivity : BaseActivity() {
        override fun onCreate(savedInstanceState: Bundle) {                
            val x = prefs.getXXX //use prefs variable from parent class
        }
    }
    
  • 这是我的应用组件:

    @Singleton @Component(modules = arrayOf(
                    ApplicationModule::class,
                    ActivityBindingModule::class,
                    AndroidSupportInjectionModule::class
                ))
    interface ApplicationComponent {
        @Component.Builder interface Builder {
            @BindsInstance
            fun application(application: Application): Builder
            fun build(): ApplicationComponent
        }
        fun inject(app: AndroidApplication)
    }
    
  • ApplicationModule 类具有简单的 @Provides 注释方法:

    @Module
    class ApplicationModule {
        @Singleton @Provides
        fun providesMyPreferenceDataStore(context: Context): MyPreferenceDataStore {
            return MyPreferenceDataStoreImpl(context)
        }
        // more @Provides annotated methods
    }
    

    我认为问题出在我的ActivityBindingModule

    @Module
    abstract class ActivityBindingModule {
    
        @PerActivity
        @ContributesAndroidInjector(
            modules = arrayOf(BaseActivityModule::class
        ))
        abstract fun bindBaseActivity(): BaseActivity
    
        @PerActivity
        @ContributesAndroidInjector(
            modules = arrayOf(
                BaseActivityModule::class
        ))
        abstract fun bindSubClassActivity(): SubClassActivity
    }
    

这是我迄今为止尝试过的:

  • 使bindSubClassActivity() 方法不依赖于BaseActivityModule::class,没有用。

  • providesMyPreferenceDataStoreApplicationModule移动到BaseActivityModule,这样类就是:

    @Module
    class BaseActivityModule {
        @PerActivity @Provides
        fun providesMyPreferenceDataStore(context: Context): MyPreferenceDataStore {
            return MyPreferenceDataStoreImpl(context)
        }
    }
    

这是我得到的错误:

Error: [dagger.android.AndroidInjector.inject(T)] com.example.BaseActivity cannot
be provided without an @Provides-annotated method.
This type supports members injection but cannot
be implicitly provided.

【问题讨论】:

  • BaseActivityModule 代码在哪里?
  • 嗨@AhmedAbd-Elmeged,请参阅编辑。

标签: android dependency-injection kotlin dagger-2


【解决方案1】:

我不完全理解你试图做什么,但这个解决方案基于我的理解

AppComponent 应该是这样的

@Singleton
@Component(modules = [
    AndroidSupportInjectionModule::class,
    AppModule::class,
    ActivityModule::class])
interface AppComponent : AndroidInjector<DaggerApplication> {

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

        fun build(): AppComponent
    }
}

将注入所有对象的基本活动

abstract class BaseActivity : DaggerAppCompatActivity() {

    @Inject
    lateinit var prefs: SharedPreferences

    //other objects to inject

}

将从它继承的活动例如:MainActivity

class MainActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        prefs.getBoolean("s", true)
    }

}

和Activity模块

@Module
abstract class ActivityModule {

    @ContributesAndroidInjector
    abstract fun bindMainActivity(): MainActivity

    @ContributesAndroidInjector
    abstract fun bindBaseActivity():BaseActivity

}

应用模块

@Module
class AppModule {

    @Singleton
    @Provides
    fun providesMyPreferenceDataStore(application: Application): SharedPreferences {
        return application.getSharedPreferences("test", Context.MODE_PRIVATE)
    }

}

【讨论】:

  • 成功了。现在我有另一个问题,但它是另一个问题的一部分。谢谢!
  • OK没问题问:D
  • 我必须编辑整个问题。将在此处发布另一个并让您知道。
  • 我认为最好提出新问题,这样如果有人遇到同样的问题,可以找到解决方案
  • 所以,我们必须在 ActivityModule 中添加所有扩展 BaseActivity / BaseFragment 的活动 / 片段,对吗?@AhmedAbd-Elmeged @JorgeE.Hernández
猜你喜欢
  • 1970-01-01
  • 2014-10-19
  • 2020-01-19
  • 2011-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
相关资源
最近更新 更多