Dagger2 中使用 AndroidInjection 优化注入流程

每个 Activity 如果都需要手动inject(this)有点繁琐,com.google.dagger:dagger-android中包含AndroidInjection类可以优化注册。

1.在 BaseActivity 中注册

abstract class BaseActivity:AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
    }
}

注意一定要在super.onCreate(savedInstanceState)之前。其他 Activity 继承 BaseActivity 即可。
同理,BaseFragment 也要这样操作,大同小异。这里以 v4 包的 Fragment 举例:

abstract class BaseFragment:Fragment() {
    override fun onAttach(context: Context?) {
        AndroidSupportInjection.inject(this)
        super.onAttach(context)
    }
}

与 Activity 不同,这里在 onAttach 中注册。

2.创建 MainActivitySub

@Subcomponent(modules = [(StudentModule::class)])
interface MainActivitySub : AndroidInjector<MainActivity> {
    @Subcomponent.Builder
    abstract class Builder:AndroidInjector.Builder<MainActivity>()
}

这里多说几句,StudentModule 是 Student 类对应的 Module,Student 类需要注入 MainActivity,MainActivity 继承自 BaseActivity。这几个类简单就不贴了,详情见 源码
如果项目中有 Fragment,那么它对应的 Sub 接口这样写:

@Subcomponent(modules = [(PersonModule::class)])
interface TestFragmentSub:AndroidInjector<TestFragment>{
    @Subcomponent.Builder
    abstract class Builder:AndroidInjector.Builder<TestFragment>()
}

上面这两个接口都使用了 Builder 模式。

3.创建 ActivityModule

@Module(subcomponents = [(MainActivitySub::class)])
abstract class ActivityModule {
    @Binds
    @IntoMap
    @ActivityKey(MainActivity::class)
    abstract fun bindMainActivity(builder: MainActivitySub.Builder): AndroidInjector.Factory<out Activity>
}
  • 所有 Activity 都要在 ActivityModule 中添加:
@ActivityKey(XXXActivity::class)
  • 每个 Activity 都要建立对应的 XXXActivitySub 接口(上面第 2 步),而且这些 XXXActivitySub 接口都要添加到 ActivityModule 的subcomponents中:
@Module(subcomponents = [(XXXActivitySub::class),(YYYActivitySub::class)])

FragmentModule 也是一样的套路

@Module(subcomponents = [(TestFragmentSub::class)])
abstract class FragmentModule {
    @Binds
    @IntoMap
    @FragmentKey(TestFragment::class)
    abstract fun bindTestFragment(builder: TestFragmentSub.Builder): AndroidInjector.Factory<out Fragment>
}

4.创建 ApplicationSub

@Component(modules = [(ActivityModule::class), (FragmentModule::class)])
interface ApplicationSub {
    fun inject(app: MyApp)
}

ApplicationSub 管理 ActivityModule 和 FragmentModule,而这两个类管理所有的 Activity 和 Fragment,这样,就只需要在 Application 中初始化就好了。

5.初始化

class MyApp : Application(), HasActivityInjector, HasSupportFragmentInjector  {

    @Inject
    lateinit var activityInjector: DispatchingAndroidInjector<Activity>
    @Inject
    lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>

    override fun onCreate() {
        super.onCreate()
        DaggerApplicationSub.create().inject(this)
    }

    override fun activityInjector(): DispatchingAndroidInjector<Activity> {
        return activityInjector
    }

    override fun supportFragmentInjector(): DispatchingAndroidInjector<Fragment> {
        return fragmentInjector
    }
}

6.其他说明

  • 我使用的开发环境是gradle:3.1.2 + kotlin_version = '1.2.30',需要在 app.gradle 里面添加apply plugin: 'kotlin-kapt'
  • 使用针对 Android 的 dagger 地址:
kapt 'com.google.dagger:dagger-compiler:2.12'
implementation 'com.google.dagger:dagger-android:2.12'
implementation 'com.google.dagger:dagger-android-support:2.12'
  • Rebuild 的时候会提示如下红色日志,这个不影响,可以直接运行项目:
Folder D:\workspace\Dagger2Sample-master\app\build\generated\source\kaptKotlin\debug

Folder D:\workspace\Dagger2Sample-master\app\build\generated\source\kaptKotlin\release

3rd-party Gradle plug-ins may be the cause

最后,
源码地址


其他几篇的链接:
Dagger2 中的 Qualifier
Dagger2 中的 Scope、dependencies
Dagger2 中的 SubComponent
Dagger2 中的 Binds、IntoSet、IntoMap


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值