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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容