Dagger2 使用

Dagger

Dagger 是一款依赖注入框架。

项目地址:dagger

官方文档:Dagger

依赖注入

依赖注入(Dependency Injection),简称DI,又叫控制反转(Inversion of Control),简称IOC。
当一个类的实例需要另另一个类的实例进行协助时,在传统的设计中,通常由调用者来创建被调用者的实例,然而依赖注入的方式,创建被调用者不再由调用者创建实例,创建被调用者的实例的工作由IOC容器来完成,然后注入到调用者。因此也被称为依赖注入。

作用:将各层的对象以松耦合的方式组织在一起,解耦,各层对象的调用完全面向接口。当系统重构或者修改的时候,代码的改写量将大大减少。

Android Studio 引入Dagger2

1
2
3
4
implementation 'com.google.dagger:dagger-android:2.17'
implementation 'com.google.dagger:dagger-android-support:2.17'
annotationProcessor 'com.google.dagger:dagger-compiler:2.17'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.17'

注解

  • Inject:主要有两个作用,一个是使用在构造函数上,通过标记构造函数让 Dagger2 来使用(Dagger2 通过 Inject 标记可以在需要这个类实 例的时候来找到这个构造函数并把相关实例 new 出来)从而提供依赖,另一个作用就是标记在需要依赖的变量让 Dagger2 为其提供依赖。

  • Provides:用来标注一个方法,该方法可以在需要提供依赖时被调用,从而把预先提供好的对象当做依赖给标注 了@Injection 的变量赋值。Provides 主要用于标注 Module 里的方法。

  • Module:用 Module 标注的类是专门用来提供依赖的。有的人可能有些疑惑,看了上面的 @Inject,需要在构造函数上标记才能提供依赖,那么如果我们需要提供 的类构造函数无法修改怎么办,比如一些jar包里的类,我们无法修改源码。这时候就需要使用 Module 了。Module 可以给不能修改源码的类提供依 赖,当然,能用 Inject 标注的通过 Module 也可以提供依赖。
  • Component:一般用来标注接口,被标注了Component的接口在编译时会产生相应的类的实例来作为提供依赖方和需要依赖方之间的桥梁,把相关依赖注入到其中。

  • Scope:自定义生命周期。其实就是说的在这个Component中可以又几个这样的对象。如果是普通的就可能有很多个,如果是Scope修饰的,就只有一个。

  • Qualifier:自定义标记。

  • Singleton:单例。需要非常注意的是:单例是基于 Component 的,所以不仅 Provides 的地方要加 @Singleton,Component 上也需要加。并且如果有另外一个 OtherActivity ,并且创建了一个 MainComponent ,也注入 Person ,这个时候 MainActivity 和 OtherActivity 中的 Person 是不构成单例的,因为它们的 Component 是不同的。

参考文章

Dagger2 for android

BaseApplication.kt

1
2
3
4
5
class BaseApplication : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.builder().injectBaseApplication(this).build()
}
}

AppComponent.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
@Singleton
@Component(modules = [AndroidInjectionModule::class, ActivityModule::class, HttpModule::class])
interface AppComponent : AndroidInjector<BaseApplication> {

@Component.Builder
interface Builder {

fun build(): AppComponent

@BindsInstance
fun injectBaseApplication(application: Application): Builder
}
}

HttpModule.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Module
class HttpModule {

@Singleton
@Provides
fun provideAipService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}

@Singleton
@Provides
fun provideRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
}

@Singleton
@Provides
fun provideOkHttpClient(interceptor: HttpLoggingInterceptor, cookieJar: PersistentCookieJar): OkHttpClient {
return OkHttpClientFactory.createUnsafeOkHttpClient(interceptor, cookieJar)
}

@Singleton
@Provides
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
}

@Singleton
@Provides
fun provideCookieJar(context: Context): PersistentCookieJar {
return CookieManager.getInstance(context).getCookieJar()
}
}

ActivityModule.kt

1
2
3
4
5
6
7
@Module
abstract class ActivityModule {

@ContributesAndroidInjector
abstract fun contributeMainActivity(): MainActivity

}

注意:

  1. ActivityModules的主要作用就是通过@ContributesAndroidInjector来标记哪个类需要使用依赖注入功能,这里标记的是ManActivity,所以MainActivity能通过@Inject注解来注入对象。

  2. @Binds 主要作用就是确定接口与具体的具体实现类,

参考文章:

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×

keyboard_arrow_up 回到顶端