如果你已經(jīng)閱讀了本文的第一部分栗菜,那么你應(yīng)該對(duì)本項(xiàng)目的modules以及結(jié)構(gòu)都比較清楚》缣猓現(xiàn)在我們繼續(xù)饮笛。咨察。。
你能夠介紹一下Dagger怎么將core中的各個(gè)modules以及MVP的各個(gè)層連接在一起嗎福青?

Dagger2使用Modules扎拣,Components和SubComponents來(lái)知道需要注入什么以及怎么注入依賴。你可以找到很多介紹Dagger內(nèi)部原理的文章。
Dagger示意圖中二蓝,從下往上我們可以看到CacheModule和SearchModule誉券,兩者都分別提供了View和Presenter:
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被CacheSubComponent和SearchSubComponet使用炬藤,這兩個(gè)component是ApplicationComponent的子Component,稍后我將在appmodule中做介紹碴里。
在core中有兩個(gè)module幫助我們提供Retrofit依賴沈矿,分別是ApiModule和ClientModule。熟悉Retrofit2將有助你理解這一部分的代碼咬腋,在本文的第三部分我也會(huì)做詳細(xì)的介紹羹膳。
所有這些module和DataBaseModule都被ApplicationComponent使用,這一部分我會(huì)在app module中介紹根竿。
現(xiàn)在來(lái)看看使用Dagger后app module內(nèi)部是什么樣子
appmodule中最重要的Dagger部分是:ApplicationComponent使用AndroidModule和ApplicationModule來(lái)提供所有的Application注入陵像。
ApplicationComonent內(nèi)容:
1.AndroidModule:
這個(gè)module提供了Application Context和Resources用于注入,在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)容增拥。
在此示例中铺董,SearchSubComponent和CacheSubComponent添加到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è)SubComponent到ApplicationComponent瑟押,并在相應(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播玖,所有繼承自BaseActivity的Activity和繼承自BaseFragment的Fragment就可以使用了椎工。BaseActivity和BaseFragment都是抽象類,他們的injectDependencies都必須在子類中實(shí)現(xiàn)蜀踏。
怎樣學(xué)習(xí)更多的Dagger內(nèi)容维蒙?!
如果你愿意果覆,你可以學(xué)習(xí)跟多關(guān)于Dagger的內(nèi)容颅痊。
可以閱讀一下這篇文章,這篇文章詳細(xì)介紹了怎么注入一切內(nèi)容局待。斑响。菱属。。我在在樣例項(xiàng)目中舰罚,appmodule中的APPSearchModule和APPCacheModule分別繼承自core中的SearchModule和CacheModule纽门。
請(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