0x00 開始
以最無趣的 “Hello World” 開始吧。
public class Hello {
public String greeting(){
return "Hello World.";
}
}
然后在 TextView 中顯示,常規(guī)的方法是:
Hello hello = new Hello();
textViewHello.setText(hello.greeting());
那么,如果使用 Dagger2 進(jìn)行依賴注入,我們使用 @Inject 將 Hello 實例注入:
@Inject Hello hello;
...
textViewHello.setText(hello.greeting());
這里存在一個問題:要怎么實例化 Hello 呢? Dagger2 提供 @Inject 標(biāo)注,在構(gòu)造函數(shù)中標(biāo)注后,當(dāng)需要實例化時,Dagger2 就會調(diào)用這個構(gòu)造函數(shù):
@Singleton
public class Hello {
@Inject public Hello() {}
public String greeting(){
return "Hello World.";
}
}
PS: 加入 Hello 也需要注入其他類呢? @Inject 同樣輕松搞定,構(gòu)造函數(shù)參數(shù)以及類成員屬性均可輕松注入。
這時依然無法工作,如果你運行程序,會產(chǎn)生悲傷的 NullPointerException,那么還差什么呢?
我們需要創(chuàng)建一個Component,Component是Provider和Injector之間的橋梁。
@Singleton
@Component
public interface DemoComponent {
void inject(MainActivity activity);
}
Dagger2 會自動生成一個 DaggerDemoComponent,在 Activity 中調(diào)用注入:
DaggerDemoComponent.create().inject(this);
打完收工!
當(dāng)然,你還需要通過 gradle 引入 Dagger2:
...
apply plugin: 'com.neenbedankt.android-apt'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
}
...
dependencies {
...
provided 'javax.annotation:javax.annotation-api:1.2'
apt 'com.google.dagger:dagger-compiler:2.0.2'
compile 'com.google.dagger:dagger:2.0.2'
}
0x01 進(jìn)階
如上所述,我們自己寫的代碼可以通過 @Inject 實例化并注入,但若是第三方庫提供的類呢?
這時需要用到 @Module, @Provide:
@Module
Module 是擁有可以提供依賴的函數(shù)的類,我們定義一個類,標(biāo)注為 @Module,然后 Dagger2 就知道哪里可以找到構(gòu)建一個對象所需要的依賴?yán)病6?Module 被設(shè)計為可以被分割和組合的模式,有益于模塊的劃分。
@Provide
在標(biāo)注為 @Module 的類中的函數(shù)可以標(biāo)注為 @Provide, 標(biāo)示可以提供相應(yīng)的依賴,函數(shù)的前綴必須為 provides.
@Module
public class DemoModule {
@Provides @Singleton
public GithubService provideGithubService() {
return new GithubService();
}
}
然后我們要告知 Component 使用這個 Module:
@Singleton
@Component(modules = {DemoModule.class})
public interface DemoComponent {
void inject(MainActivity activity);
}
@Component 可以通過 dependencies 申明依賴依他的 @Component。
@Singleton
這是標(biāo)示一個單例的注釋,可以和 @Provide 共同標(biāo)注一個函數(shù),標(biāo)示這個函數(shù)返回的對象都是單例的,也可以和 @Component 一起標(biāo)注一個Component,標(biāo)示這個 Component 的 Scope 是全局的。
@Scope
Scopes 非常的有用,Dagger2 可以通過自定義注解限定注解作用域。
@Qualifier
當(dāng)類的類型不足以鑒別一個依賴的時候,我們就可以使用這個注解標(biāo)示。
例如:在Android中,我們會需要不同類型的 Context,所以我們就可以定義 Qualifier 注解 @ForApplication 和 @ForActivity,這樣當(dāng)注入一個 Context 的時候,我們就可以告訴 Dagger 我們想要哪種類型的 Context。