Dagger依賴注入框架(入門)

目錄

    1. Dagger簡(jiǎn)介
    1. Dagger1.x冗澈,Dagger2.x簡(jiǎn)單對(duì)比
    1. 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)缸浦。

依賴注入的幾種方式

  1. 構(gòu)造函數(shù)注入
// Constructor
Client(Service service) {
    // Save the reference to the passed-in
    // service inside this client
    this.service = service;
}
  1. setter方法注入
// Setter method
public void setService(Service service) {
    // Save the reference to the passed-in
    // service inside this client
    this.service = service;
}
  1. 接口注入
// 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不生效的地方:

  1. 注解接口不生效灾票,因?yàn)榻涌诓荒鼙粚?shí)例化峡谊。
  2. 注入第三方j(luò)ar包里的類不生效,因?yàn)檫@樣的類不能被@Inject注解。
  3. 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ì)象綁定到集合中戴差。

  1. 注解 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 定義的墨吓。
  1. 注解集合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í)例棚亩。ModuleProvide方法是靜態(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ì)象如何獲戎莸堋?

  1. 會(huì)通過(guò)Dagger低零。先找有沒(méi)有Module提供CoffeeMaker對(duì)象,如果沒(méi)有拯杠,再找有沒(méi)有@Inject注解的構(gòu)造器掏婶。
  2. 找到構(gòu)造器之后,發(fā)現(xiàn)CoffeeMaker構(gòu)造器有兩個(gè)參數(shù)潭陪,那個(gè)這兩個(gè)參數(shù)也是注入的雄妥。
  3. 再找有沒(méi)有提供參數(shù)的Provider方法,因?yàn)橹奥暶髁?strong>Component接口依溯,把ModuleCoffeeMaker關(guān)聯(lián)了老厌,這里會(huì)去DripCoffeeModuleProvider方法。這里也就解釋了為什么還需要在CoffeeMaker中傳入依賴黎炉,最為構(gòu)造函數(shù)的參數(shù)枝秤。
  4. 最終完成注入

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的注入流程差不多瞬矩。步驟如下:

  1. 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
}
  1. 在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);
    }
    //...
}
  1. 定義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ǔ)充蛇摸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市灿巧,隨后出現(xiàn)的幾起案子赶袄,更是在濱河造成了極大的恐慌揽涮,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弃鸦,死亡現(xiàn)場(chǎng)離奇詭異绞吁,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)唬格,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門家破,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人购岗,你說(shuō)我怎么就攤上這事汰聋。” “怎么了喊积?”我有些...
    開(kāi)封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵烹困,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我乾吻,道長(zhǎng)髓梅,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任绎签,我火速辦了婚禮枯饿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诡必。我一直安慰自己奢方,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布爸舒。 她就那樣靜靜地躺著蟋字,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扭勉。 梳的紋絲不亂的頭發(fā)上鹊奖,一...
    開(kāi)封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音剖效,去河邊找鬼嫉入。 笑死,一個(gè)胖子當(dāng)著我的面吹牛璧尸,可吹牛的內(nèi)容都是我干的咒林。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼爷光,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼垫竞!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤欢瞪,失蹤者是張志新(化名)和其女友劉穎活烙,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體遣鼓,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡啸盏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了骑祟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片回懦。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖次企,靈堂內(nèi)的尸體忽然破棺而出怯晕,到底是詐尸還是另有隱情,我是刑警寧澤缸棵,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布舟茶,位于F島的核電站,受9級(jí)特大地震影響堵第,放射性物質(zhì)發(fā)生泄漏吧凉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一踏志、第九天 我趴在偏房一處隱蔽的房頂上張望客燕。 院中可真熱鬧,春花似錦狰贯、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至幔摸,卻和暖如春摸柄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背既忆。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工驱负, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人患雇。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓跃脊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親苛吱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酪术,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容