關(guān)于Dagger2的一些使用及介紹

Dagger2是一個(gè)Android依賴(lài)注入框架,由Google Fork 的 Square公司的Dagger基礎(chǔ)上再開(kāi)發(fā)琴儿。傳統(tǒng)的MVC框架Activity比較臃腫孕索,難以維護(hù),現(xiàn)在主流的架構(gòu)還是使用MVP(Mode + View + Presenter)的方式赛惩。但是MVP框架也有可能在Presenter中集中大量代碼哀墓,引入Dagger2可以實(shí)現(xiàn)Presenter與Activity直接的解耦,提高模塊化和可維護(hù)性喷兼。Jake Wharton 在對(duì) Dagger 的介紹中指出篮绰,Dagger 即 DAG-er,這里的 DAG 即數(shù)據(jù)結(jié)構(gòu)中的 DAG——有向無(wú)環(huán)圖(Directed Acyclic Graph)季惯。也就是說(shuō)吠各,Dagger 是一個(gè)基于有向無(wú)環(huán)圖結(jié)構(gòu)的依賴(lài)注入庫(kù),因此Dagger的使用過(guò)程中不能出現(xiàn)循環(huán)依賴(lài)勉抓。

Dagger2

基本特點(diǎn)(反射機(jī)制):

  • 沒(méi)有反射贾漏,在編譯時(shí)執(zhí)行(圖的驗(yàn)證、配置和預(yù)先設(shè)置)
  • 容易調(diào)試和可跟蹤(具體的調(diào)用和創(chuàng)建堆棧)
  • 代碼混淆(使用派遣方法)

Dagger2通過(guò)注解來(lái)生成代碼藕筋,定義不同角色纵散,主要的注解有:@Inject、@Module隐圾、@Componet伍掀、@Provides、@Scope暇藏、@SubComponet等

? @Inject: 通常在需要依賴(lài)的地方使用這個(gè)注解蜜笤。換句話(huà)說(shuō),你用它告訴Dagger這個(gè)類(lèi)或者字段需要依賴(lài)注入盐碱。這樣瘩例,Dagger就會(huì)構(gòu)造一個(gè)這個(gè)類(lèi)的實(shí)例并滿(mǎn)足他們的依賴(lài)。

? @Module: Modules類(lèi)里面的方法專(zhuān)門(mén)提供依賴(lài)甸各,所以我們定義一個(gè)類(lèi)垛贤,用@Module注解,這樣Dagger在構(gòu)造類(lèi)的實(shí)例的時(shí)候趣倾,就知道從哪里去找到需要的 依賴(lài)聘惦。modules的一個(gè)重要特征是它們?cè)O(shè)計(jì)為分區(qū)并組合在一起(比如說(shuō),在我們的app中可以有多個(gè)組成在一起的modules)。

? @Provides: 在modules中善绎,我們定義的方法是用這個(gè)注解黔漂,以此來(lái)告訴Dagger我們想要構(gòu)造對(duì)象并提供這些依賴(lài)。

? @Component: Components從根本上來(lái)說(shuō)就是一個(gè)注入器禀酱,也可以說(shuō)是@Inject和@Module的橋梁炬守,它的主要作用就是連接這兩個(gè)部分。 Components可以提供所有定義了的類(lèi)型的實(shí)例剂跟,比如:我們必須用@Component注解一個(gè)接口然后列出所有的   @Modules組成該組件减途,如 果缺失了任何一塊都會(huì)在編譯的時(shí)候報(bào)錯(cuò)。所有的組件都可以通過(guò)它的modules知道依賴(lài)的范圍曹洽。
  @Scope: Scopes可是非常的有用鳍置,Dagger2可以通過(guò)自定義注解限定注解作用域。這是一個(gè)非常強(qiáng)大的特點(diǎn)送淆,因?yàn)闆](méi)必要讓每個(gè)對(duì)象都去了解如何管理他們的實(shí)例税产。

? Qualifier: 當(dāng)類(lèi)的類(lèi)型不足以鑒別一個(gè)依賴(lài)的時(shí)候,我們就可以使用這個(gè)注解標(biāo)示偷崩。例如:在Android中辟拷,我們會(huì)需要不同類(lèi)型的context,所以我們就可以定義 qualifier注解“@ForApplication”和“@ForActivity”阐斜,這樣當(dāng)注入一個(gè)context的時(shí)候衫冻,我們就可以告訴 Dagger我們想要哪種類(lèi)型的context。

上代碼

bulid.gradle(Project)

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.1'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

build.gradle(Module)

compile 'com.google.dagger:dagger:2.0.2'
compile 'com.google.dagger:dagger-compiler:2.0.2'
provided 'org.glassfish:javax.annotation:10.0-b28'

項(xiàng)目結(jié)構(gòu)圖

  • ?本項(xiàng)目提供兩個(gè)例子智听,分別是兩種不同的框架注入模式 具體代碼后面給鏈接

  • 第一種方式

    對(duì)于不同的Activity羽杰,創(chuàng)建各個(gè)對(duì)應(yīng)的ActivityCompontent,同時(shí)把Presenter(Biz)注入到Component的視圖中到推,這也是dagger2推薦的做法考赛,Dagger 2希望使用@Component注解接口將依賴(lài)關(guān)系鏈接起來(lái)。

Paste_Image.png

di包下面是一些跟隨Application生命周期的依賴(lài)方法與實(shí)例莉测,其中AppModule與AppServiceModule提供了全局的Context與User類(lèi)颜骤,UI包下面就是具體的MVP的代碼

Appmodule.java

@Module
public class AppModule {
    private final App application;

    public AppModule(App application) {
        this.application = application;
    }

    @Provides
    @Singleton
    App provideApplicationContext() {
        return application;
    }

}

AppServiceModule.java

@Module
public class AppServiceModule {

    @Provides
    User provideUser() {
        User user = new User();
        user.setId("1");
        user.setName("hello world");
        return user;
    }
}

Modules類(lèi)里面的方法專(zhuān)門(mén)提供依賴(lài)

?

UI下面的代碼

@ActivityScope
@Component(modules = LoginAcivityModule.class, dependencies = AppComponent.class)
public interface LoginActivityComponent {

    LoginActivity inject(LoginActivity mainActivity);

    LoginActivityPresenter presenter();
}
@Module
public class LoginAcivityModule {

    private LoginActivity mLoginActivity;

    public LoginAcivityModule(LoginActivity loginActivity) {
        this.mLoginActivity = loginActivity;
    }


    @Provides
    @ActivityScope
    LoginActivity provideMainActivity() {
        return mLoginActivity;
    }


    @Provides
    @ActivityScope
    LoginActivityPresenter provideMainActivityPresenter(LoginActivity loginActivity, User user) {
        return new LoginActivityPresenter(loginActivity, user);
    }
}
public class LoginActivityPresenter {

    private LoginActivity mainActivity;
    private User user;

    public LoginActivityPresenter(LoginActivity mainActivity, User user) {
        this.mainActivity = mainActivity;
        this.user = user;
    }


    public void showUserName() {
        System.out.println(user.getName());
        mainActivity.setUserName(user.getName());
    }
}

到這注入初步就可以了。

使用:

public class LoginActivity extends BaseActivity {

    private TextView mytext;

    @Inject
    LoginActivityPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mytext = (TextView) findViewById(R.id.mytext);

        presenter.showUserName();

    }

    @Override
    protected void setupActivityComponent(AppComponent appComponent) {
        DaggerLoginActivityComponent.builder()
                .appComponent(appComponent)
                .loginAcivityModule(new LoginAcivityModule(this))
                .build()
                .inject(this);
    }

    public void setUserName(String userName){
        mytext.setText(userName);
    }


}

Dagger生成的代碼

  • 這里只介紹LoginActivity捣卤,AppComponent生成是一樣的忍抽。

  • DaggerLoginActivityComponent.build會(huì)創(chuàng)建LoginActivity_MembersInjector,LoginActivity_MembersInjector會(huì)為L(zhǎng)oginActivity的所有注入成員提供依賴(lài)董朝,只要調(diào)用inject()鸠项,就能獲取所需的字段和依賴(lài)。

  • 在引用inject的時(shí)候子姜,Dagger會(huì)為我們生成祟绊,上面的例子則會(huì)生成LoginAcivityModule_ProvideMainActivityPresenterFactory的工廠(chǎng),這個(gè)工廠(chǎng)實(shí)現(xiàn)就是創(chuàng)建了LoginActivityPresenter的實(shí)例。

Paste_Image.png
  • DaggerLoginActivityComponent類(lèi)牧抽,我們有一個(gè)Provider嘉熊,它不僅僅是一個(gè)提供實(shí)例的接口,它還是被ScopedProvider構(gòu)造出來(lái)的扬舒,可以記錄創(chuàng)建實(shí)例的范圍阐肤。

end

到此Dagger2的簡(jiǎn)單使用就差不多了,另外還有一種MVP方式結(jié)合的Dagger2例子讲坎,第二個(gè)例子是沒(méi)有將Presenter是注入到Component中的,好處就是節(jié)省了代碼孕惜。下面給出例子源碼鏈接

源碼

https://github.com/xiahao2014/Dagger2MVP

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市衣赶,隨后出現(xiàn)的幾起案子诊赊,更是在濱河造成了極大的恐慌厚满,老刑警劉巖府瞄,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異碘箍,居然都是意外死亡遵馆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)丰榴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)货邓,“玉大人,你說(shuō)我怎么就攤上這事四濒』豢觯” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵盗蟆,是天一觀的道長(zhǎng)戈二。 經(jīng)常有香客問(wèn)我,道長(zhǎng)喳资,這世上最難降的妖魔是什么觉吭? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮仆邓,結(jié)果婚禮上鲜滩,老公的妹妹穿的比我還像新娘。我一直安慰自己节值,他們只是感情好徙硅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著搞疗,像睡著了一般嗓蘑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天脐往,我揣著相機(jī)與錄音休吠,去河邊找鬼。 笑死业簿,一個(gè)胖子當(dāng)著我的面吹牛瘤礁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梅尤,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼柜思,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了巷燥?” 一聲冷哼從身側(cè)響起赡盘,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缰揪,沒(méi)想到半個(gè)月后谈喳,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體级历,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了驾中。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耙册。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡聘殖,死狀恐怖瘪菌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情毫目,我是刑警寧澤蔬啡,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站镀虐,受9級(jí)特大地震影響箱蟆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粉私,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一顽腾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诺核,春花似錦抄肖、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至入客,卻和暖如春管毙,著一層夾襖步出監(jiān)牢的瞬間腿椎,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工夭咬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留啃炸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓卓舵,卻偏偏與公主長(zhǎng)得像南用,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子掏湾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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