从零开始搭建一个项目(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

推荐阅读更多精彩内容