[譯]MVP實(shí)踐(Android)-Part2:Dagger使用

如果你已經(jīng)閱讀了本文的第一部分栗菜,那么你應(yīng)該對(duì)本項(xiàng)目的modules以及結(jié)構(gòu)都比較清楚》缣猓現(xiàn)在我們繼續(xù)饮笛。咨察。。

你能夠介紹一下Dagger怎么將core中的各個(gè)modules以及MVP的各個(gè)層連接在一起嗎福青?

Dagger示意圖
Dagger示意圖

Dagger2使用Modules扎拣,ComponentsSubComponents來(lái)知道需要注入什么以及怎么注入依賴。你可以找到很多介紹Dagger內(nèi)部原理的文章。

Dagger示意圖中二蓝,從下往上我們可以看到CacheModuleSearchModule誉券,兩者都分別提供了ViewPresenter

package com.mirhoseini.marvel.character.cache;

import dagger.Module;
import dagger.Provides;

@Module
class CacheModule {

    private CacheView view;

    CacheModule(CacheView view) {
        this.view = view;
    }

    @Provides
    public CacheView provideView() {
        return view;
    }

    @Provides
    @Cache
    public CachePresenter providePresenter(CachePresenterImpl presenter) {
        presenter.bind(view);
        return presenter;
    }

}
package com.mirhoseini.marvel.character.search;

import dagger.Module;
import dagger.Provides;

@Module
class SearchModule {

    private SearchView view;

    SearchModule(SearchView view) {
        this.view = view;
    }

    @Provides
    public SearchView provideView() {
        return view;
    }

    @Provides
    @Search
    public SearchInteractor provideInteractor(SearchInteractorImpl interactor) {
        return interactor;
    }

    @Provides
    @Search
    public SearchPresenter providePresenter(SearchPresenterImpl presenter) {
        presenter.bind(view);
        return presenter;
    }

}

首先,請(qǐng)注意provide方法的返回類型刊愚,他們都是返回接口踊跟,而不是具體接口的實(shí)現(xiàn)!這就是為什么在后續(xù)的測(cè)試中我們可以替換掉具體的實(shí)現(xiàn)鸥诽。我必須指出來(lái)這里是SOLID原則中開閉原則商玫,里氏替換原則依賴反轉(zhuǎn)原則的一個(gè)混合體。

其次牡借,不要忘記我們現(xiàn)在還處于coremodule拳昌,我們還不知道View將怎么使用這些代碼。

最后钠龙,這兩個(gè)module被CacheSubComponentSearchSubComponet使用炬藤,這兩個(gè)component是ApplicationComponent的子Component,稍后我將在appmodule中做介紹碴里。

core中有兩個(gè)module幫助我們提供Retrofit依賴沈矿,分別是ApiModuleClientModule。熟悉Retrofit2將有助你理解這一部分的代碼咬腋,在本文的第三部分我也會(huì)做詳細(xì)的介紹羹膳。

所有這些module和DataBaseModule都被ApplicationComponent使用,這一部分我會(huì)在app module中介紹根竿。

現(xiàn)在來(lái)看看使用Dagger后app module內(nèi)部是什么樣子

appmodule中最重要的Dagger部分是:ApplicationComponent使用AndroidModuleApplicationModule來(lái)提供所有的Application注入陵像。

ApplicationComonent內(nèi)容:

1.AndroidModule

這個(gè)module提供了Application ContextResources用于注入,在android開發(fā)中使用Context和Resources可以很方便的訪問(wèn)到一系列Services和不同的Resources寇壳。有的開發(fā)者喜歡在ApplicationModule中實(shí)現(xiàn)這個(gè)module醒颖,但是我更喜歡將它獨(dú)立出來(lái)這樣會(huì)更加清晰。

這個(gè)module將在MarvelApplication中創(chuàng)建九巡,MarvelApplication繼承自Application類:

package com.mirhoseini.marvel;

import android.app.Application;

public abstract class MarvelApplication extends Application {

    private static ApplicationComponent component;

    public static ApplicationComponent getComponent() {
        return component;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        initApplication();

        component = createComponent();
    }

    public ApplicationComponent createComponent() {
        return DaggerApplicationComponent.builder()
                .androidModule(new AndroidModule(this))
                .build();
    }

    public abstract void initApplication();

}

你可能已經(jīng)注意到這個(gè)類是一個(gè)抽象類图贸,通過(guò)debug或者release編譯類型來(lái)實(shí)現(xiàn)initApplication()方法來(lái)完成,這對(duì)于在release版本或者debug版本中做一些不同的操作是非常方便的冕广。

在這個(gè)實(shí)例中疏日, 我通過(guò)debug版本的MarvelApplicationImpl來(lái)引入Timber庫(kù),從而避免在release版本中輸出Timber log:

package com.mirhoseini.marvel;

import timber.log.Timber;

public class MarvelApplicationImpl extends MarvelApplication {

    @Override
    public void initApplication() {

        // 在debug版本中初始化 Timber 用于log輸出
        Timber.plant(new Timber.DebugTree() {
            @Override
            protected String createStackElementTag(StackTraceElement element) {
                // 在log中輸出代碼行號(hào)
                return super.createStackElementTag(element) + ":" + element.getLineNumber();
            }
        });

    }
}

2.ApplicationModule

這個(gè)module幾乎提供了所有的Application需求:

  • isDebug:用BuildConfig.DEBUG來(lái)判斷當(dāng)前運(yùn)行的應(yīng)用實(shí)例是否為debug模式撒汉,進(jìn)而確定是否在log輸出中打印網(wǎng)絡(luò)API的信息沟优。
  • networkTimeoutInSeconds, cacheSize, cacheMaxAge, cacheMaxStale, cacheDir:提供為Retrofit創(chuàng)建OkHttp client時(shí)所需要的網(wǎng)絡(luò)參數(shù)。
  • endpoint:為retrofit提供API的endpoint睬辐。
  • appSchedule:提供RxAndroid調(diào)度者挠阁,詳細(xì)內(nèi)容我將在RxJava部分介紹宾肺。
  • isConnect:提供網(wǎng)絡(luò)狀態(tài),用于處理離線情況侵俗。

3.ApiModule,ClientModule

4.DatabaseModule

5.subComponents:

Dagger的好處是可以添加SubComponent锨用,你可以添加SubComponent到你的主ApplicationComponent,你可以添加你自己的注入內(nèi)容隘谣,你也可以使用所有它提供的注入內(nèi)容增拥。

在此示例中铺董,SearchSubComponentCacheSubComponent添加到ApplicationComponent并使其更加出色单旁。

SearchSubComponent 和 CacheSubComponent:

一起來(lái)看一下ApplicationComponent:

package com.mirhoseini.marvel;
/*...*/

@Singleton
@Component(modules = {
        AndroidModule.class,
        ApplicationModule.class,
        ApiModule.class,
        DatabaseModule.class,
        ClientModule.class
})
public interface ApplicationComponent {
        
    void inject(MainActivity activity);
    SearchSubComponent plus(AppSearchModule module);
    CacheSubComponent plus(AppCacheModule module);
        
}

如你所見壹罚,我們已經(jīng)使用了inject方法用于注入党涕,但是那些plus方法是什么鬼?赃份!

首先饿这,我需要指出inject和plus都只是名字E桌觥噪珊!你可以修改為任意你喜歡的名字晌缘,Dagger會(huì)檢查方法的輸入輸出從而確定它的用途。但是請(qǐng)不要讓你的團(tuán)隊(duì)成員在以后閱讀這份代碼時(shí)找不著北卿城。枚钓。铅搓。

使用plus方法你可以要求Dagger添加一個(gè)SubComponentApplicationComponent瑟押,并在相應(yīng)的SubComponent中去實(shí)現(xiàn)inject方法。

plus方法使用Module作為參數(shù)星掰,返回一個(gè)SubComponent多望,這個(gè)SubComponent使用的module為plus方法傳入的參數(shù)。

一起來(lái)仔細(xì)的看一下:

package com.mirhoseini.marvel.character.search;

import dagger.Subcomponent;

@Search
@Subcomponent(modules = {
        AppSearchModule.class
})
public interface SearchSubComponent {

    void inject(CharacterSearchFragment fragment);

}

好啦好啦氢烘,那么Dagger集成是從哪里開始的呢怀偷?

簡(jiǎn)單的修改一下manifest,我們可以要求Android使用MarvelApplication的實(shí)現(xiàn)作為應(yīng)用的入口:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.mirhoseini.marvel">

    <!-- *** -->

    <application
        android:name=".MarvelApplicationImpl"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
       
        <!-- *** -->
       
    </application>

</manifest>

我們一旦在MarvelApplication中創(chuàng)建了Application component播玖,所有繼承自BaseActivityActivity和繼承自BaseFragmentFragment就可以使用了椎工。BaseActivityBaseFragment都是抽象類,他們的injectDependencies都必須在子類中實(shí)現(xiàn)蜀踏。

怎樣學(xué)習(xí)更多的Dagger內(nèi)容维蒙?!

如果你愿意果覆,你可以學(xué)習(xí)跟多關(guān)于Dagger的內(nèi)容颅痊。

可以閱讀一下這篇文章,這篇文章詳細(xì)介紹了怎么注入一切內(nèi)容局待。斑响。菱属。。我在在樣例項(xiàng)目中舰罚,appmodule中的APPSearchModuleAPPCacheModule分別繼承自core中的SearchModuleCacheModule纽门。

請(qǐng)從github上clone一份代碼并熟悉一下,因?yàn)閺南乱徊糠治覍⒏嗟慕榻Bretrofit以及它是怎么幫助我們使用網(wǎng)絡(luò)API調(diào)用以及緩存使用营罢。

我期待您的意見和幫助以便更好的改進(jìn)這篇文章膜毁。

繼續(xù)下一篇:MVP實(shí)踐(Android)-Part3:使用Retrofit調(diào)用API

原文鏈接:Yet another MVP article?—?Part 2: How Dagger helps with the project

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市愤钾,隨后出現(xiàn)的幾起案子瘟滨,更是在濱河造成了極大的恐慌,老刑警劉巖能颁,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杂瘸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡伙菊,警方通過(guò)查閱死者的電腦和手機(jī)败玉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)镜硕,“玉大人运翼,你說(shuō)我怎么就攤上這事⌒丝荩” “怎么了血淌?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)财剖。 經(jīng)常有香客問(wèn)我悠夯,道長(zhǎng),這世上最難降的妖魔是什么躺坟? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任沦补,我火速辦了婚禮,結(jié)果婚禮上咪橙,老公的妹妹穿的比我還像新娘夕膀。我一直安慰自己,他們只是感情好美侦,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布产舞。 她就那樣靜靜地躺著,像睡著了一般音榜。 火紅的嫁衣襯著肌膚如雪庞瘸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天赠叼,我揣著相機(jī)與錄音擦囊,去河邊找鬼违霞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瞬场,可吹牛的內(nèi)容都是我干的买鸽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼贯被,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼眼五!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起彤灶,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤看幼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后幌陕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诵姜,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年搏熄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了棚唆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡心例,死狀恐怖宵凌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情止后,我是刑警寧澤瞎惫,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站坯门,受9級(jí)特大地震影響微饥,放射性物質(zhì)發(fā)生泄漏逗扒。R本人自食惡果不足惜古戴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望矩肩。 院中可真熱鬧现恼,春花似錦、人聲如沸黍檩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)刽酱。三九已至喳逛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間棵里,已是汗流浹背润文。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工姐呐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人典蝌。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓曙砂,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親骏掀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鸠澈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

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