從零開始搭建一個項目(rxJava+Retrofit+Dagger2) --完結篇

雞湯:感到迷茫是因為你沒有給自己做好人生規劃

接上一章的內容,如果還沒看過的朋友,
請點

從零開始系列第0章
從零開始系列第1章
從零開始系列第2章
從零開始系列完結章

本章內容
Dagger2的引入

Dagger2的引入

Dagger2是一個依賴注入框架,那么dagger2能起什么作用呢?
簡單點講就是

dagger2會幫你維護好一些對象,你需要什么對象,可以直接問dagger2要,
當然前提是你已經按照dagger2的要求寫了好這些依賴。

比如:像下圖這種情況,你需要得到result,那你不得不像代碼那樣,先得到c對象,得到c對象,就需要得到b對象,需要得到a對象。

public class Dagger2Test{
    private classA a;
    private classB b;
    private classC c;
    private String result;

    public void onCreate() {
        super.onCreate();
        b=new classB(a);
        c=new classC(b);
        result=c.get(0);
    }

}

而使用了dagger2的話,可以寫成這樣

public class Dagger2Test{
   //一個直接得到c對象,然后在oncreate中一行代碼搞定
   @Inject
   classC c;
    
    private TestComponent mComponent;

    private String result;

    public void onCreate() {
        super.onCreate();
        mComponent.inject(this);
        result=c.get(0);
    }
}

Dagger2的引入
在config.gradle(不知道config.gradle如何來的,請看系列文章第0章)設置依賴

//版本號
 daggerVersion = '2.2'
javaxAnnotationVersion = '1.0'
//遠程依賴
 dependencies = [
        daggerCompiler:     "com.google.dagger:dagger-compiler:${daggerVersion}",
        dagger:             "com.google.dagger:dagger:${daggerVersion}",
        javaxAnnotation:    "javax.annotation:jsr250-api:${javaxAnnotationVersion}"
]

build.gradle下

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
        //加入dagger2的apt插件
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

app/build.gradle下
文件頂部

//引入dagger2 的apt插件
apply plugin: 'com.neenbedankt.android-apt'
//添加依賴
apt dependency['daggerCompiler']
compile dependency['dagger']
compile dependency['javaxAnnotation']

做完上述的工作,dagger2就已經引入成功了。

在項目中使用

首先回顧一下在開源項目2中的代碼,在事件的起點view,也就是TodayGankFragment中,有段代碼是這樣的!

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    RxFlux rxFlux = RxFlux.init(MyApplication.getApplication());
    Dispatcher dispatcher = rxFlux.getDispatcher();
    SubscriptionManager manager = rxFlux.getSubscriptionManager();

    store = new TodayGankStore(dispatcher);

    dispatcher.subscribeRxStore(store);
    dispatcher.subscribeRxView(this);

    creator = new TodayGankActionCreator(dispatcher, manager);
    //view從對應的Creator請求數據
    creator.getTodayGank();
}

上述代碼中最重要的,不可或缺的,不能再縮減的代碼有這么幾句

//兩個監聽注冊
dispatcher.subscribeRxStore(store);
dispatcher.subscribeRxView(this);

//view從對應的Creator請求數據
creator.getTodayGank();

兩個subscribe監聽注冊,以及數據請求,數據請求是事件的起點,subscribe是為了之后的數據流轉所必須的。

除了這三行代碼,其他的變量和對象的聲明都可以想辦法放到別處,使得這段代碼變得簡潔。

這個時候Daggar2就可以排上用場了。

首先來整理下依賴,我們的需要的依賴對象或者變量有
RxFlux
dispatcher
manager
store
creator
一個有5個依賴,再根據業務邏輯將5個依賴劃分一下,
RxFlux,dispatcher,manager這三個依賴屬于全局型依賴,就是說很多地方都需要用的到的依賴。
而store和creator只是局部型依賴,所以單獨處理。

全局依賴

定義一個AppComponent類,具體寫法不在累述。

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
    //
    Dispatcher getDispatcher();

    SubscriptionManager getSubscriptManager();

}

AppComponent類提供Dispatcher和SubscriptionManager兩個對象,具體的實現在AppModule類中

@Module
public class AppModule {

    private final RxFlux mRxFlux;

    public AppModule(MyApplication application) {
        mApplication = application;
        //初始化RxFlux
        mRxFlux = RxFlux.init(application);
    }

    @Provides
    @Singleton
    Dispatcher provideDispatcher() {
        return mRxFlux.getDispatcher();
    }

    @Provides
    @Singleton
    SubscriptionManager provideSubscriptManager() {
        return mRxFlux.getSubscriptionManager();
    }

}

構造函數里初始化RxFlux,然后借用RxFlux,初始化Dispatcher和SubscriptionManager對象。

調用:
在程序入口MyApplication中使用

public class MyApplication extends Application {

    private static AppComponent mAppComponent;

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

    private void initInjector() {
        mAppComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .build();
    }

    public static AppComponent getAppComponent() {
        return mAppComponent;
    }
}

在MyApplication中initInjector()方法執行之后,RxFlux,Dispatcher和SubscriptionManager三個依賴對象就初始化成功了。

接下來還需要store和creator這兩個依賴,
定義一個TodayGankFragmentComponent類

@PerActivity
@Component(dependencies = {AppComponent.class})
public interface TodayGankFragmentComponent {

    void inject(TodayGankFragment todayGankFragment);
}

PerActivity類,聲明scope,不然會報錯

@Scope
@Retention(RUNTIME)
public @interface PerActivity {}

在TodayGankFragment中,使用TodayGankFragmentComponent,注意appComponent的時候要把你之前定義好的appComponent對象傳進去,

private void initInjector() {
    TodayGankFragmentComponent mComponent= DaggerTodayGankFragmentComponent.builder()
            .appComponent(MyApplication.getAppComponent())
            .build();
    mComponent.inject(this);
}

這個時候你就可以很簡單的聲明對象了,

比如TodayGankStore類中,先在構造方法上加上@Inject注解,表示我能接受一個dispatcher參數,并提供一個TodayGankStore對象,而dispatcher這個對象在最開始的appComponent中就已經初始化完成,

@Inject
public TodayGankStore(Dispatcher dispatcher) {
    super(dispatcher);
}

在需求類中,即TodayGankFragment中,聲明TodayGankStore對象store,這個store就是TodayGankStore所提供的,這中間的過程Dagger2會幫你處理。

@Inject TodayGankStore store;

單獨解釋一下@Inject這個注解的作用
1.標記在構造方法上,表示對象提供者
2.標記在目標類中,表示實例對象。

加入了dagger2之后,代碼變化如下,

@Inject TodayGankStore mStore;
@Inject TodayGankActionCreator mActionCreator;
@Inject Dispatcher mDispatcher;    

 @Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    //RxFlux rxFlux = RxFlux.init(MyApplication.getApplication());
    //Dispatcher dispatcher = rxFlux.getDispatcher();
    //SubscriptionManager manager = rxFlux.getSubscriptionManager();
    //store = new TodayGankStore(dispatcher);
    //dispatcher.subscribeRxStore(store);
    //dispatcher.subscribeRxView(this);
    //creator = new TodayGankActionCreator(dispatcher, manager);
    //view從對應的Creator請求數據
    //creator.getTodayGank();

    mDispatcher.subscribeRxStore(mStore);
    mDispatcher.subscribeRxView(this);
    mActionCreator.getTodayGank();
}

注釋的代碼是沒加Dagger2之前的,可以明顯的看出依賴關系簡單了很多,代碼邏輯也清晰了許多。

Dagger2還是能夠給代碼帶來挺大的變化的。
本來還想再寫一點基類封裝的內容,不過由于部分代碼和業務邏輯關系比較緊,要寫的話,內容還有不少。
所以留到下次再講吧!

本人也只是Android開發路上一只稍大一點的菜鳥,如果各位讀者中發現文章中有誤之處,請幫忙指出,你的批評和鼓勵都是我前進的動力。

寫在文末:如果讀者朋友有什么問題或者意見可以在評論里指出.
代碼地址為https://github.com/niknowzcd/FluxDemo3

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容