Dagger2 学习笔记

听说Dagger2和Retrolambda很久了,本来是拒绝的,觉得只是锦上填一点小花而已,但最近看来,Github上已经有很多开源项目采用,再不学就又落后面了……

看完下面这三篇就差不多了,其他很多都是重复的,Dagger2是唯一的我感觉看完官方的讲解还无从下手

  • http://blog.fidroid.com/post/android/dagger-on-android-dagger2xiang-jie

  • http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0519/2892.html

  • https://github.com/konmik/konmik.github.io/wiki/Snorkeling-with-Dagger-2

再配合我fork过来的一个例子,我正在做完善,原作者是做示例Dagger2 + RxJava + MVP, 我打算做成完善的

  • https://github.com/kyleada/Comedy

一般的使用和原理就齐活了~

Dagger2的使用配置:在build.gradle

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.huxian"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        renderscriptTargetApi 19
        renderscriptSupportModeEnabled false
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    apt 'com.google.dagger:dagger-compiler:2.0'
    compile 'javax.annotation:jsr250-api:1.0'
    compile 'com.google.dagger:dagger:2.0'

}

下面是我理解的用法,一个用过Spring IoC的Android开发工程师

Spring IoC用起来非常好上手

提供依赖的,用@Component注解,需要依赖的地方 用@Autowired注解,配置文件加上component-scan就差不多了。
因为接口可能有多个实现,也有@qualifier提供过滤
实现是依赖反射,涉及动态生成类

Dagger2感觉并不太好上手
提供依赖的类用@Module注解
能提供的依赖用@Provide注解,(这是因为给第三方提供依赖用的,自己的类提供依赖,只需要在构造函数上加上@Inject即可)
需要依赖的地方 用@Inject注解,
最终要靠手动调用inject方法完成依赖的注入,这个inject方法要在@Compoent的类里提供。
Dagger2为了性能考虑,没有使用反射,注解是编译时处理。
另外Spring提供的默认单例实现貌似只能是应用级的单例,而Dagger2提供了Scope的概念,可以配合声明周期使用,分成应用级,Activity级等

上面的博客说的最清楚的还是 https://github.com/konmik/konmik.github.io/wiki/Snorkeling-with-Dagger-2
尤其是building完后,对照build/generated/sources/apt/下生成的文件加断点,才能理解好整个过程

采用MVP开发模式时,需要在Activity或Fragment里诸如Presenter,看上面注明的Comedy工程

   @Inject MovieDetailPresenter movieDetailPresenter;

这种写法movieDetailPresenter在调用inject是已经生成,如果想在使用时才生成对象有两种办法
一种是使用Lazy< MovieDetailPresenter >
一种按照后来我改写的, ActorDetailActivity 里不再是通过@Inject方式提供movieDetailPresenter,而是改由在ActorDetailComponent里声明
ActorDetailPresenter actorDetailPresenter();方法提供.
这样可以实现在调用actorDetailPresenter时才生成对象。这种情况可以应用在ViewPager里Framgent可见时才去获取,进而发网络请求

注意:ActorDetailPresenter actorDetailPresenter();这里方法名字不重要,重要的还是返回值。编译时,需要让编译期能生成构造出ActorDetailPresenter 对象的方法。这个也有两种办法:
一种是在ActorDetailPresenter 的构造函数声明@inject,告诉编译器需要ActorDetailPresenter 对象时从这里构造就可以
一种是在Module里以@Provide的形式提供。


    @Provides
    @ActivityScope
    ActorDetailPresenter provideActorDetailPresenter(GetActorDetailUsecase getActorDetailUsecase){
        return new ActorDetailPresenter(getActorDetailUsecase);
    }

如果这两个都没写呢,编译时会有提示:
com.huxian.presenter.ActorDetailPresenter cannot be provided without an @Inject constructor or from an @Provides-annotated method.
提示说的很清楚

再说一下Angualr 1.x里的依赖注入,同样是Google家搞出来的东西,它的使用更简单一些。
简单说,就是在Controller依赖Service,而Service提供了三种方法定义,这里的定义也就是告诉了Angualr框架该怎么构造出这些可以被依赖的对象。在Controller里呢,简洁写法只需要在对应function里的入参写上Service名字就OK了~

你可能感兴趣的:(android,Dagger2)