美文网首页Android开发今日看点Android架构
从零开始搭建一个项目(rxJava+Retrofit+Dagge

从零开始搭建一个项目(rxJava+Retrofit+Dagge

作者: niknowzcd | 来源:发表于2016-12-27 22:41 被阅读3140次

    鸡汤:感到迷茫是因为你没有给自己做好人生规划

    接上一章的内容,如果还没看过的朋友,
    请点

    从零开始系列第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

    相关文章

      网友评论

      本文标题:从零开始搭建一个项目(rxJava+Retrofit+Dagge

      本文链接:https://www.haomeiwen.com/subject/ihdevttx.html