目錄
- Dagger簡(jiǎn)介
- Dagger1.x冗澈,Dagger2.x簡(jiǎn)單對(duì)比
-
- Dagger中的注解
- @Inject
- @Provide
- @Module
- @Component
- @Binds
- multibinds
- 其他關(guān)鍵注解
- 4.使用
- 5.Dagger & Android
- Activity的注入
- Fragment的注入
Dagger官方文檔
Dagger&Android
Dagger分享(這一篇筆記也很好,內(nèi)容全面易懂,排版也很清晰颂翼,可以參考學(xué)習(xí))
DaggerDamo(文中的Dagger&Android的Demo都是參考這里寫的)
1. Dagger簡(jiǎn)介:
依賴注入的框架。依賴注入的目的——解耦妻枕。
依賴注入的常規(guī)方式
如果class A中有class B的實(shí)例焦辅,就可以說(shuō)A依賴于B,如MVP中婚惫,V(Activity)持有P(Presenter)氛赐,V依賴于P,這個(gè)例子存在一個(gè)問(wèn)題先舷,如果有一天艰管,B的構(gòu)造方法變了,那我們就需要修改A中創(chuàng)建B的代碼蒋川,而且所有創(chuàng)建B實(shí)例的地方牲芋,都需要修改。
———— 如果使用Dagger來(lái)進(jìn)行依賴注入捺球,只需要用@Inject
和其他注解就能實(shí)現(xiàn)缸浦。
依賴注入的幾種方式
- 構(gòu)造函數(shù)注入
// Constructor
Client(Service service) {
// Save the reference to the passed-in
// service inside this client
this.service = service;
}
- setter方法注入
// Setter method
public void setService(Service service) {
// Save the reference to the passed-in
// service inside this client
this.service = service;
}
- 接口注入
// Service setter interface.
public interface ServiceSetter {
public void setService(Service service);
}
// Client class
public class Client implements ServiceSetter {
// Internal reference to the service used by this
// client.
private Service service;
// Set the service that this client is to use.
@Override
public void setService(Service service) {
this.service = service;
}
}
2. Dagger1.x -> Dagger2.x
更好的性能:相較于Dagger1,它使用的預(yù)編譯期間生成代碼來(lái)完成依賴注入氮兵,而不是用的反射裂逐。大家知道反射對(duì)手機(jī)應(yīng)用開(kāi)發(fā)影響是比較大的,因?yàn)榉瓷涫窃诔绦蜻\(yùn)行時(shí)加載類來(lái)進(jìn)行處理所以會(huì)比較耗時(shí)胆剧,而手機(jī)硬件資源有限絮姆,所以相對(duì)來(lái)說(shuō)會(huì)對(duì)性能產(chǎn)生一定的影響。
容易跟蹤調(diào)試:因?yàn)閐agger2是使用生成代碼來(lái)實(shí)現(xiàn)完整依賴注入秩霍,所以完全可以在相關(guān)代碼處下斷點(diǎn)進(jìn)行運(yùn)行調(diào)試.
3. Dagger中的注解
@Inject
@Inject篙悯,兩個(gè)作用,其一:用來(lái)標(biāo)記構(gòu)造函數(shù)铃绒,Dagger可以調(diào)用它創(chuàng)建該類的實(shí)例鸽照,對(duì)外提供依賴。其二:標(biāo)記依賴字段颠悬,表示該字段由Dagger提供實(shí)例矮燎。也就是標(biāo)記依賴源和依賴宿主。
如果一個(gè)類有@Inject注解的字段赔癌,但是沒(méi)有@Inject注解的構(gòu)造器(注入jar包中的類)诞外,可以使用方法注入——@Provide注解。
@Inject不生效的地方:
- 注解接口不生效灾票,因?yàn)榻涌诓荒鼙粚?shí)例化峡谊。
- 注入第三方j(luò)ar包里的類不生效,因?yàn)檫@樣的類不能被@Inject注解。
- Configurable objects must be configured!
對(duì)于這些不能使用@Inject進(jìn)行注入的地方既们,可以使用@Provider注解的方法提供依賴濒析。
@Provide
@Provide用來(lái)注解方法,該方法用于提供依賴啥纸。當(dāng)需要Dagger提供依賴注入的時(shí)候号杏,這個(gè)方法會(huì)被調(diào)用——?jiǎng)?chuàng)建依賴對(duì)象。
@Module
@Module用于注解類斯棒,該類用于提供依賴盾致。
@Component
@Component一般用來(lái)標(biāo)注接口,被標(biāo)注了Component的接口名船,在編譯時(shí)會(huì)由Dagger生成接口的實(shí)例绰上,作為提供依賴方(Module)和依賴宿主的橋梁,或者說(shuō)注入器渠驼,把相關(guān)依賴注入到宿主容器中蜈块。
@Component(modules = DripCoffeeModule.class)
public interface CoffeeShop {
CoffeeMaker maker();
}
Component中有兩個(gè)方法:
-
Provision:Provision方法如上,不接收參數(shù)迷扇,返回值是被注入的依賴類型百揭,這個(gè)class必須有
@Inject
注解的構(gòu)造器,或者有module創(chuàng)建這個(gè)依賴的實(shí)例蜓席。 - Member-injection: Member-injection方法有一個(gè)參數(shù)器一,用于傳入依賴的宿主,如果依賴宿主不能由Dagger實(shí)例化(如Activity)厨内,就可以使用這種方式進(jìn)行注入祈秕。
void injectMembers(T)
@Binds
如果我們需要一個(gè)一般化的類型,而Dagger的object graph中已經(jīng)一個(gè)該類型的子類雏胃,那么用Provide是這樣做的:
@Provides
static Pump providePump(Thermosiphon pump) {
return pump;
}
用 Binds 注解可以這么做:
@Binds
static abstract Pump providePump(Thermosiphon pump);
@Binds 用于注解方法聲明请毛,如果 module 是接口,那么 binds 方法就是一個(gè)方法聲明瞭亮,如果 module 是類方仿,那么 binds 方法就是一個(gè)abstract方法。 binds 方法有且只有一個(gè)參數(shù)统翩,這個(gè)參數(shù)可以賦值給返回值類型仙蚜。也就是說(shuō)參數(shù)是返回接口的子類。
注意 Module 不能同時(shí)用 Binds 方法和 Provide 非static方法,因?yàn)?Binds 方法只是一個(gè)方法聲明沒(méi)有實(shí)現(xiàn)厂汗,一旦 Module 有了 Provide 方法(非static)委粉,意味著這個(gè) Module 必須實(shí)例化,所以方法聲明就必須得有實(shí)現(xiàn)娶桦,這便起了沖突艳丛。當(dāng)然匣掸,如果 Provide 方法是static的趟紊,那也是可以的氮双。
multibinds
multibinds不是一個(gè)注解,而是用于multibinds的一組注解霎匈。用于將對(duì)象綁定到集合中戴差。
- 注解 Provider 方法,表示提供的對(duì)象會(huì)被注入 Set/Map铛嘱。
Set:
- @IntoSet 將一個(gè)元素注入 Set
- @ElementsIntoSet 將一個(gè)集合注入 Set
Map
@IntoMap 表示該方法的返回值作為 Map 的 value 注入 Map 中暖释,另外 Key 由下面的注解提供:
- @Stringkey 提供字符串作為 key
- @IntKey 提供 int
- @ClassKey 提供 class
- 也可用 @MapKey 自定義 key 的類型
key 都是常量
在dagger-android中我們會(huì)看到 @ActivityKey 注解,就是通過(guò)@MapKey 定義的墨吓。
- 注解集合Set/Map球匕,@Multibinds
對(duì)于 @Inject 注解的集合,找不到元素提供方的話帖烘,dagger 會(huì)在編譯期報(bào)錯(cuò):
java.util.Map<java.lang.String,java.lang.String> cannot be provided without an @Provides- or @Produces-annotated method.
如果有在 Module 中聲明了 @Multibinds亮曹,便不會(huì)報(bào)錯(cuò),而是得到一個(gè)空集合秘症。具體例子可以看dagger-android中的Activity注入照卦。
注意:Module注解的優(yōu)先級(jí)高于構(gòu)造器注解。
其他關(guān)鍵注解
@Scope: Dagger2可以通過(guò)自定義注解限定注解作用域乡摹,來(lái)管理每個(gè)對(duì)象實(shí)例的生命周期役耕,在它的生命周期范圍內(nèi),提供單例聪廉。
@Qualifier: 有時(shí)只靠類型瞬痘,不足以識(shí)別一個(gè)依賴,可能無(wú)法找到依賴提供方板熊。比如我們注入的是一個(gè)特殊的接口實(shí)現(xiàn)框全,與默認(rèn)實(shí)現(xiàn)有區(qū)別(可能是構(gòu)造參數(shù)不同),這時(shí)邻邮,我們需要@Qualifiers聲明一個(gè)額外的注解竣况,用于區(qū)分依賴。
例如:在Android中筒严,我們會(huì)需要不同類型的context丹泉,所以我們就可以定義 Qualifier注解@perApp
和@perActivity
,這樣當(dāng)注入一個(gè)context的時(shí)候鸭蛙,我們就可以告訴 Dagger我們想要哪種類型的context摹恨。
@Singleton:可以在@Providers方法或依賴類聲明中使用該注解∪⑹樱可在全局范圍內(nèi)提供注入類的單例晒哄。
@Provides
@Singleton
static Heater provideHeater() {
return new ElectricHeater();
}
@Singleton
class CoffeeMaker {
...
}
Component需要和Scope關(guān)聯(lián)起來(lái)睁宰,一個(gè)Component不能既有@Singleton的依賴,又有@RequestScoped的依賴寝凌,因?yàn)槎叩淖饔糜虿煌馍担芷谝膊煌?/p>
@Component(modules = DripCoffeeModule.class)
@Singleton
interface CoffeeShop {
CoffeeMaker maker();
}
4.使用
背景:假設(shè)我們有一個(gè)咖啡機(jī)(CoffeeMaker),可以加熱咖啡(Heater)较木,有泵可以抽出咖啡(Pump)『旆現(xiàn)在,我們需要在CoffeeMaker中注入這兩個(gè)裝置伐债,完成功能組合预侯。
1. 定義依賴接口
//加熱裝置
public interface Heater {
void on();
void off();
boolean isHot();
}
public interface Pump {
void pump();
}
2.定義依賴宿主CoffeeMaker
,使用@Inject
注入依賴峰锁。
注意:我們注入的依賴萎馅,除了有@Inject注解的字段之外,還需要通過(guò)構(gòu)造函數(shù)參數(shù)傳入虹蒋。
public class CoffeeMaker {
@Inject Heater heater;
@Inject Pump pump;
CoffeeMaker(Heater heater, Pump pump) {
this.heater = heater;
this.pump = pump;
}
public void brew() {
heater.on();
pump.pump();
System.out.println(" [_]P coffee! [_]P ");
heater.off();
}
}
3.使用@Module糜芳,定義依賴提供方。
ElectricHeater是Heater的實(shí)現(xiàn)類千诬。Thermosiphon是Pump的實(shí)現(xiàn)類耍目。
@Module
public class DripCoffeeModule {
@Provides static Heater provideHeater() {
return new ElectricHeater();
}
@Provides static Pump providePump(Thermosiphon pump) {
return pump;
}
}
4.使用@Component定義注入器接口,完成Module和依賴宿主的關(guān)聯(lián)徐绑。
@Component(modules = DripCoffeeModule.class)
public interface CoffeeShop {
CoffeeMaker maker();
}
返回的CoffeeMaker對(duì)象也由Dagger提供邪驮。修改CoffeeMaker的構(gòu)造函數(shù),添加@Inject傲茄。
@Inject
CoffeeMaker(Heater heater, Pump pump) {
this.heater = heater;
this.pump = pump;
}
5.在Activity或Main方法中通過(guò)Component獲取CoffeeMaker實(shí)例毅访。
可以發(fā)現(xiàn),我們并沒(méi)有實(shí)現(xiàn)DaggerCoffeeShop
盘榨,這里為什么可以調(diào)用呢喻粹?因?yàn)樵诰幾g期間,Dagger自動(dòng)為我們的Component接口生成實(shí)現(xiàn)類草巡,DaggerCoffeeShop
就是CoffeeShop
接口的實(shí)例.
dripCoffeeModule ()
守呜,該方法根據(jù)Component綁定的Module自動(dòng)生成,傳入Module實(shí)例山憨。
CoffeeShop coffeeShop = DaggerCoffeeShop.builder()
.dripCoffeeModule(new DripCoffeeModule())
.build();
coffeeShop.maker().brew();
以上查乒,就完成了依賴注入。
但是存在一個(gè)問(wèn)題:Module對(duì)應(yīng)一個(gè)默認(rèn)的構(gòu)造器郁竟,Dagger在編譯期間生成的DaggerCoffeeShop
玛迄,可以訪問(wèn)Module,獲取依賴實(shí)例棚亩。Module的Provide方法是靜態(tài)的蓖议,不需要我們手動(dòng)構(gòu)造Module實(shí)例就可以訪問(wèn)其Provide方法虏杰。—— 所以勒虾,我們可以使用create()
代替build()
纺阔。
CoffeeShop coffeeShop = DaggerCoffeeShop.create();
coffeeShop.maker().brew();
我們使用Component關(guān)聯(lián)依賴提供方法(Module)和依賴宿主。并返回CoffeeMaker對(duì)象从撼,這個(gè)CoffeeMaker對(duì)象如何獲戎莸堋?
- 會(huì)通過(guò)Dagger低零。先找有沒(méi)有Module提供CoffeeMaker對(duì)象,如果沒(méi)有拯杠,再找有沒(méi)有@Inject注解的構(gòu)造器掏婶。
- 找到構(gòu)造器之后,發(fā)現(xiàn)
CoffeeMaker
構(gòu)造器有兩個(gè)參數(shù)潭陪,那個(gè)這兩個(gè)參數(shù)也是注入的雄妥。 - 再找有沒(méi)有提供參數(shù)的Provider方法,因?yàn)橹奥暶髁?strong>Component接口依溯,把Module和
CoffeeMaker
關(guān)聯(lián)了老厌,這里會(huì)去DripCoffeeModule
找Provider方法。這里也就解釋了為什么還需要在CoffeeMaker
中傳入依賴黎炉,最為構(gòu)造函數(shù)的參數(shù)枝秤。 - 最終完成注入
5.Dagger & Android
Dagger相比于其他依賴注入框架,優(yōu)點(diǎn)在于它完全靜態(tài)生成依賴慷嗜。
Dagger在Android中使用的特點(diǎn)在于淀弹,Android中很多組件是由Framework進(jìn)行實(shí)例化的。常規(guī)的注入方式庆械,是通過(guò)構(gòu)造函數(shù)參數(shù)傳遞依賴薇溃。但是在Android中,顯然不能由Dagger創(chuàng)建Activity/Fragment缭乘,無(wú)法訪問(wèn)到其構(gòu)造函數(shù)沐序。所以,我們必須在組件的生命周期方法內(nèi)進(jìn)行成員的注入堕绩。
常規(guī)的注入方式策幼,通過(guò)構(gòu)造函數(shù)傳遞依賴
public class CoffeeMaker {
//通過(guò)Module提供注入——DripCoffeeModule
@Inject Heater heater;
@Inject Pump pump;
@Inject
CoffeeMaker(Heater heater, Pump pump) {
this.heater = heater;
this.pump = pump;
}
}
Android中的注入
/**
* 給Application用的component,可以作為一個(gè)全局的component逛尚,如果其他的Activity需要使用垄惧,從Appliction中獲取,以此達(dá)到復(fù)用的目的绰寞。
* 將依賴提供方AppModule和依賴宿主FeatureActivity關(guān)聯(lián)起來(lái)
*/
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
//需要我們自己聲明builder,通常builder都是Dagger自動(dòng)生成的到逊,但是在Android中注入Activity铣口,需要我們自己聲明,提供component
@Component.Builder
interface Builder {
@BindsInstance
Builder application(App application);
AppComponent build();//提供獲取組件的方法觉壶,這個(gè)組件bind到了Application上
}
/**
* Member-injection方法,用于傳入依賴的宿主脑题,對(duì)于Activity這樣的組件,不能由Dagger進(jìn)行實(shí)例化铜靶,無(wú)法在其構(gòu)造器上添加注入的參數(shù)叔遂,需要中這種方式進(jìn)行注入
*/
void inject(FeatureActivity featureActivity);
}
@Module
public class AppModule {
@Provides
Context provideContext(App application) {
return application.getApplicationContext();
}
@Singleton
@Provides
SomeClientApi provideSomeClientApi() {
return new SomeClientApiImpl();
}
}
public class App extends Application {
//將Component綁定到Application,Activity需要使用時(shí)争剿,通過(guò)Application獲取該組件已艰,達(dá)到復(fù)用的目的
private AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent
.builder()
.application(this)
.build();
}
public AppComponent getAppComponent() {
return appComponent;
}
}
在Android中,framework為我們初始化了Activity蚕苇,除了使用@Inject
注解注入的變量之外哩掺,我們需要調(diào)用component的members injection方法完成注入。
public class FeatureActivity extends AppCompatActivity {
//在Activity中注入api,通過(guò)Application獲取
@Inject
SomeClientApi mSomeClientApi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在Activity的生命周期方法內(nèi)完成注入
((App) getApplication())
.getAppComponent()
.inject(this);
//調(diào)用注入的依賴
mSomeClientApi.report();
}
}
以上是在Activity注入一個(gè)依賴的全部步驟涩笤,但是這樣的注入方式帶來(lái)的問(wèn)題:
- 在其他需要注入這個(gè)依賴的Activity中嚼吞,會(huì)在
onCreate()
寫這樣的重復(fù)代碼。 - 被注入方——Activity蹬碧,它知道我們是如何注入一個(gè)依賴的舱禽,用什么注入器(Component),注入器怎么調(diào)用恩沽。這樣違反了依賴注入的原則:一個(gè)類不需要知道它如何被注入依賴的誊稚。
使用dagger-android module進(jìn)行依賴注入
1. 添加dagger-android依賴
// Dagger core dependencies
implementation 'com.google.dagger:dagger:2.16'
annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
// Dagger Android dependencies
implementation 'com.google.dagger:dagger-android:2.16'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.16'
implementation 'com.google.dagger:dagger-android-support:2.16' // if you use the support libraries
2. 定義一個(gè)@Subcomponent
接口
該component實(shí)現(xiàn) AndroidInjector<YourActivity>
接口,并聲明其內(nèi)部抽象類Builder,繼承AndroidInjector.Builder<YourActivity>
@Subcomponent
public interface FeatureSubComponent extends AndroidInjector<FeatureActivity> {
@Subcomponent.Builder
public abstract class Builder extends AndroidInjector.Builder<FeatureActivity> {}
}
3. 定義一個(gè)Module飒筑,用來(lái)bind subComponent的Builder
@Module(subcomponents = FeatureSubComponent.class)
public abstract class BuildersModule {
@Binds
@IntoMap
@ActivityKey(FeatureActivity.class)
abstract AndroidInjector.Factory<? extends Activity> bindFeatureActivityInjectorFactory(FeatureSubComponent.Builder builder);
// Add more bindings here for other sub components
}
把這個(gè)Module綁定到Application的注入容器(Component)中.此外還需要注入AndroidSupportInjectionModule
片吊。
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, AppModule.class, BuildersModule.class})
public interface AppComponent {
// void inject(FeatureActivity featureActivity);
//這里不再注入Activity,而是注入到Application中
void inject(App app);
}
4.改造Application
實(shí)現(xiàn)HasActivityInjector
接口,實(shí)現(xiàn)接口的activityInjector()
方法返回注入的 DispatchingAndroidInjector<Activity>
协屡,
最后在onCreate()
中進(jìn)行注入俏脊。
public class App extends Application implements HasActivityInjector{
@Inject
DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.create()
.inject(this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return dispatchingActivityInjector;
}
}
5. 在Activity中注入依賴
移除原來(lái)的注入代碼,改為在super.onCreate()
前調(diào)用AndroidInjection.inject(this)
肤晓。
public class FeatureActivity extends AppCompatActivity {
@Inject
SomeClientApi mSomeClientApi;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//調(diào)用依賴的方法
mSomeClientApi.report();
}
}
注入的依賴爷贫,需要宿主提供參數(shù)
有時(shí)我們注入的依賴,它的實(shí)例化參數(shù)需要宿主方提供补憾,在沒(méi)有dagger-android 的時(shí)候漫萄,需要我們?cè)?code>Activity中調(diào)用inject()
進(jìn)行注入之前,就將Activity
作為參數(shù)傳給module盈匾。如:在MVP模式中腾务,實(shí)例化P的時(shí)候,需要傳入V的實(shí)例削饵,需要我們?cè)诎?code>Activity作為Module的構(gòu)造函數(shù)的參數(shù)進(jìn)行傳遞岩瘦,再添加provider函數(shù)提供Activity未巫。
@Module
class FeatureModule {
private FeatureView view;
//構(gòu)造module的時(shí)候傳入view
public FeatureModule(FeatureView view) {
this.view = view;
}
//再把這個(gè)view提供出去
@Provides FeatureView provideView() {
return view;
}
}
//presenter中使用構(gòu)造函數(shù)注入
class FeaturePresenter {
private final FeatureView view;
@Inject
Presenter(FeatureView view) {
this.view = view;
}
public void doSomething() {
}
}
public class FeatureActivity extends AppCompatActivity implements FeatureView {
@Inject FeaturePresenter presenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在Activity中實(shí)例化FeatureModule,并把Activity作為參數(shù)
DaggerFeatureComponent.builder()
.featureModule(FeatureModule(this)).build()
.inject(this)
// presenter ready to be used
presenter.doNothing();
}
}
但是在dagger-android中启昧,Activity只調(diào)用AndroidInjection.inject(this)
進(jìn)行注入叙凡,不在Activity中初始化Module。應(yīng)該怎么進(jìn)行注入呢密末?使用dagger-android的時(shí)候握爷,activity實(shí)例已經(jīng)存在于dagger的對(duì)象圖中了,使用@Binds
严里,我們可以從對(duì)象圖中新啼,取出activity作為參數(shù),具體代碼如下:
@Module
public abstract class FeatureModule {
//使用Binds表示從Dagger的對(duì)象圖中獲取FeatureActivity實(shí)例田炭,然后將其賦值給FeatureConstrant.View师抄,參數(shù)是返回值的子類
@Binds
abstract FeatureConstrant.View provideFutureView(FeatureActivity featureActivity);
}
在presenter中添加inject構(gòu)造器,view作為參數(shù)教硫。
public class FeaturePresenter implements FeatureConstrant.Presenter {
private FeatureConstrant.View mView;
@Inject
public FeaturePresenter(FeatureConstrant.View view) {
this.mView = view;
}
//業(yè)務(wù)代碼
}
在component中加入這個(gè)module,最后在view中添加@Inject注解的presenter字段就OK辆布。
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, AppModule.class, BuildersModule.class, FeatureModule.class})
public interface AppComponent {
//...
}
注入Fragment
Fragment的注入和Activity的注入流程差不多瞬矩。步驟如下:
- Activity實(shí)現(xiàn)
HasFragmentInjector
接口。提供DispatchingAndroidInjector<Fragment>
對(duì)象锋玲。和Activity的注入有區(qū)別景用,F(xiàn)ragment是在Activity中加載的,所以在Activity中實(shí)現(xiàn)接口惭蹂。
public class FeatureActivity extends AppCompatActivity HasFragmentInjector{
@Inject
DispatchingAndroidInjector<Fragment> fragmentInjector;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
}
@Override
public AndroidInjector<Fragment> fragmentInjector() {
return fragmentInjector;
}
//other function
}
- 在Fragment中添加依賴伞插,并調(diào)用
AndroidInjection.inject(this)
進(jìn)行依賴注入。注意盾碗,inject()
需要在onAttach()
的super.onAttach(activity)
前調(diào)用媚污。
public class TextFragment extends Fragment {
//注入的依賴
@Inject
SomeClientApi mSomeClientApi;
@Override
public void onAttach(Activity activity) {
AndroidInjection.inject(this);
super.onAttach(activity);
}
//...
}
- 定義subComponent,實(shí)現(xiàn)
AndroidInjector<YourFragment>
接口廷雅,定義內(nèi)部類Builder耗美。
@Subcomponent
public interface FragmentSubComponent extends AndroidInjector<TextFragment> {
@Subcomponent.Builder
public abstract class Builder extends AndroidInjector.Builder<TextFragment> {}
}
4.把SubComponent的Builder綁定到Module。使用FragmentKey注解內(nèi)部方法航缀。
@Module(subcomponents = {OtherSubComponent.class, FragmentSubComponent.class})
public abstract class BuildersModule {
//add fragment sub component
@Binds
@IntoMap
@FragmentKey(TextFragment.class)
abstract AndroidInjector.Factory<? extends Fragment> bindFragmentInjectorFratory(FragmentSubComponent.Builder builder);
// Add more bindings here for other sub components
}
5.把Module綁定到Component商架。
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, BuildersModule.class, OtherModule.class})
public interface AppComponent {
//這里不再注入Activity,而是注入到Application中
void inject(App app);
}
6.總結(jié)
這一部分先到這里芥玉,后續(xù)想到再補(bǔ)充蛇摸。