美文网首页MVVM With KotlinAndroid进阶之路Android开发
使用Kotlin构建MVVM应用程序—提高篇:Dagger-An

使用Kotlin构建MVVM应用程序—提高篇:Dagger-An

作者: ditclear | 来源:发表于2018-06-27 15:31 被阅读140次

    写在前面

    提高篇的目的是想着写一些较深入的知识,包含一些源码分析架构设想脚手架搭建的东西。
    面向的人群是中高级的开发者或者愿意深入了解如何快速构建Kotlin&&MVVM应用的人群。

    Dagger-Android

    原本的打算是将其作为使用Kotlin构建MVVM应用程序系列的第五部分内容。
    但因为Dagger本身就有一定的入门门槛,Dagger-Android的门槛就更高了。对于初中级开发者而言,Dagger-Android太容易入门到放弃,对于这部分人群不是很适合,因此将其放入提高篇较为合适。
    又因为Dagger-Android门槛较高,对于初学者来说不适用,就如同初出江湖的小菜鸟就想着去练习远高于自己根基的武功,对自己没有太多好处,多积累基础,设计模式才是正途,能力到了自然就悟了。
    又由于曲高和寡,懂的人自然懂。为此,我开通了使用Kotlin构建MVVM应用程序的小专栏,提高篇的完整内容会放在这里,愿意去了解的了解一哈。
    而这里也就大致的总结一下它的思路。

    为什么要有Dagger-Android?

    对于这个问题,google在Dagger-Android的文档上有解释:

    我们普通的dagger代码如下所示:

    public class FrombulationActivity extends Activity {
      @Inject Frombulator frombulator;
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // DO THIS FIRST. Otherwise frombulator might be null!
        ((SomeApplicationBaseType) getContext().getApplicationContext())
            .getApplicationComponent()
            .newActivityComponentBuilder()
            .activity(this)
            .build()
            .inject(this);
        // ... now you can write the exciting code
      }
    }
    

    这会带来一些问题:

    1. 只是复制粘贴上面的代码会让以后的重构比较困难,还会让一些开发者不知道Dagger到底是如何进行注入的(然后就更不易理解了)
    2. 更重要的原因是:它要求注射类型(FrombulationActivity)知道其注射器。 即使这是通过接口而不是具体类型完成的,它打破了依赖注入的核心原则:一个类不应该知道如何实现依赖注入。

    为了解决上述的问题,Dagger-Android应运而生。
    这是它的起因,那么和传统的Dagger区别又在哪里呢?

    区别在哪?

    就在解法不同罢了,如果你认为Dagger-Android是普通Dagger的延伸,要按照Dagger的逻辑去理解Dagger-Android,那么一开始就错了。
    假设把依赖注入看成是一道算法题或者数学的最后一道大题。
    Dagger和Dagger-Android都是正确的答案,只是两个不同的解法而已。
    相比之下,Dagger-Android在程序启动的时候通过处理注解,初始化了一个全局的单例map

    Map<Class<? extends T>, Provider<AndroidInjector.Factory<? extends T>>>
    

    key值为activity/fragment的class,而value为提供相应Component的Provider对象。在开始的时候就为我们映射好了。
    当我们调用AndroidInjection.inject(this)时,也就是一个简单的map.get(instance.class).getComponent().inject(this)
    相比之下,多了一个从map去获取component的中间过程,但是却解决了上诉的第二个问题 :一个类不应该知道如何实现依赖注入。

    思路的差别就在这里,明白这一点,通过断点一步步的源码分析,Dagger-Android也没有多么高不可攀。

    快速开始

    首先我们需要在app/build.gradle加入相应的依赖

        //dagger2  di
        implementation 'com.google.dagger:dagger:2.16'
        kapt 'com.google.dagger:dagger-compiler:2.16'
        //dagger-android
        implementation 'com.google.dagger:dagger-android:2.16'
        implementation 'com.google.dagger:dagger-android-support:2.16' 
        kapt 'com.google.dagger:dagger-android-processor:2.16'
    

    注入方法建议看文档更好,这里简单描述一下:

    还是以MVVM-Android为例。

    1. 添加ActivityModule.kt
    @Module
    abstract class ActivityModule {
    
        @ContributesAndroidInjector
        abstract fun contributePaoActivity(): PaoActivity
    
    }
    

    2 . 修改AppComponent.kt

    @Singleton
    @Component(modules = arrayOf(
            AndroidInjectionModule::class,
            AppModule::class,
            ActivityModule::class)
    )
    interface AppComponent {
    
        @Component.Builder
        interface Builder {
            @BindsInstance
            fun application(application: Application): Builder
    
            fun build(): AppComponent
        }
    
        fun inject(application: PaoApp)
    }
    

    相比Dagger2,modules多了AndroidInjectionModule和ActivityModule两个类。

    1. rebuild一下项目,然后新增PaoApp.kt同时实现HasActivityInjector接口
    class PaoApp : Application(),HasActivityInjector{
    
        @Inject
        lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
    
        override fun onCreate() {
            super.onCreate()
            DaggerAppComponent.builder().application(app).build().inject(app)
        }
    
        override fun activityInjector() = dispatchingAndroidInjector
    
    }
    
    1. 最后在Activity的onCreate()方法之前调用 AndroidInjection.inject(this)进行注入
    class PaoActivity : RxAppCompatActivity() {
        @Inject
        lateinit var mViewModel : PaoViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            //////di
            AndroidInjection.inject(this)
            super.onCreate(savedInstanceState)
        }
    }
    

    到此,一个简单的依赖注入就好了。

    写在最后

    简单当然是不简单的,这里简单介绍了怎么做,具体的分析过程在小专栏中,愿意了解的可以订阅一哈 > --.>
    使用 Kotlin 构建 MVVM 应用程序—提高篇:Dagger-Android(原理剖析)

    github:https://github.com/ditclear/MVVM-Android/tree/dagger-android
    参考文档:
    Dagger-Android
    告别Dagger2模板代码:DaggerAndroid原理解析 (推荐)

    相关文章

      网友评论

      本文标题:使用Kotlin构建MVVM应用程序—提高篇:Dagger-An

      本文链接:https://www.haomeiwen.com/subject/ueibyftx.html