架构社区架构网络请求

RxJava+Realm+MVP+ARouter+Retrofi

2017-02-23  本文已影响735人  Poseidon_Wang

去年就一直想搭建一个框架,可惜一直拖到年初才有时间。熟话说基础不牢地洞山摇。当然我们要先看项目的组织结构,既然是一个通用的库,就只能包括通用的模块。
项目模块划分
|- base
|-BaseApplication
|-BaseActivity
|-BaseFragment
|-BaseActivityLifeCircleCallbak
|-db
|-message
|-network
|-okhttp
|-retrofit
|-HttpManager
|-utils
|-ARouter
|-monitor
这里我们对于模块的组合采用了Router方式,对于ios或者前端的人士应该比较熟悉,对模块复用解耦比较简单,大体项目结构如上,有些小的类就没写了,以及一些模块持续更新中。下面的讲解就以我的添加顺序来了

Network

网络模块在一个App中属于大模块,而且相对独立,所以我选择首先建立。这里选取了Retrofit+Okhttp3的插件,本身都是square出品的Retrofit与其说是为了OkHttp而生的也不过分,关于OkHttp的分析请参考我的另一篇OkHttp核心理解,关于Retrofit是基于主流请求都是restful风格,使用请参考Retrofit使用没什么大的东西,主要是对一些注解的理解。
这里可操作性比较大的就在与我们的OkHttp里面,他的精髓大概就是Interceptor了吧。
因为网络模块可以分为日志,缓存,Https,授权(废弃)。

  1. 日志模块我们往OkHttpClient里加了一个ApplicationInterceptor,获取request以及Response的信息,这里日志我用了自己上传Jcenter的项目,比Logger难看点,附上github地址BullDog
  2. 缓存这边情况比较复杂,大概讲下遇到的困难,后来就放弃了第一种方案,本来如果设计合理的话,我们其实可以使用Interceptor直接实现无网络使用缓存,有网络更新的策略。但是由于OkHttp的默认缓存是只支持Get的与我们的实际情况有所出入,反正我也讲下合理情况下的方案。
  1. Retrofit模块,这个模块没什么好讲,主要是用于写请求的,以及一些基本配置
  2. 最后加了个BaseNetWorkCallbackBean用来规范我们的网络返回

总结,这边模块分的比较多,主要遵循组合大于继承,有利于以后的拆解阅读。

DB

Db模块以前我们用的大多是core data比如说greenDao,我用的这个realm在ios平台用的比较多,网上有关于这块区别的讲解,主要还是从效率上来讲,realm明显要高出core data这块很多,有点缺陷就是对bean的污染,每个bean都要继承RealmObject,照某网友的说法就是强奸代码。Realm官方网站
我这边主要是对Realm进行了简单的封装,对一些常用操作简单化,比方说insert,query,delete由于Realm不支持sql语句查询,所以自由度相对也就差点,不过移动端不像后端需要复杂查询各种外键条件的,我封装的几个查询应该已经满足日常使用了,此外Realm还支持异步,但有一点千万要注意,Realm的操作类并非单例,你获取一个,他就线索树里面多一个引用,所以每次使用完记得释放,这里我是在BaseActivity的生命周期内控制的,只不过异步的情况要复杂一点,在api封装上也是讲realm对象作为参数传入,在最后进行释放。

Base

这个是比较基础的部分,为什么不选择先建是因为有些东西是随着模块的加入逐步完善的,比方说前面提到的Realm,还有后面的RxBus。

  1. BaseApplication,这个类的核心在于一些插件的初始化。涉及到这个如果我们的插件比较多,势必影响到APP的启动速度,所以我们最简单的处理就是启用线程池,引入异步初始化,但是需要注意有些操作是一开始就需要的只能放在同步操作里,比方说Log框架的加载。这里我封装了一个ApplicationInitializer,主要的就是使用cacheThreadPool来控制初始化,分离的目的也是为了单一职责。以下为一些类的初始化
        BLog.init();
        /* 其他初始化任务无时序要求可多线程处理 */
        cachedThreadScheduler.execute(new Runnable() {
            @Override
            public void run() {
                Realm.init(application);
                RealmConfiguration realmConfiguration = new RealmConfiguration.Builder()
                        .name(DB_NAME)
                        .deleteRealmIfMigrationNeeded()
                        .build();
                Realm.setDefaultConfiguration(realmConfiguration);
            }
        });

        cachedThreadScheduler.execute(new Runnable() {
            @Override
            public void run() {
                Fresco.initialize(application);
            }
        });
        cachedThreadScheduler.execute(new Runnable() {
            @Override
            public void run() {
//                LeakCanary.install(application);
            }
        });
        cachedThreadScheduler.execute(new Runnable() {
            @Override
            public void run() {
//                BlockCanary.install(application,new AppBlockCanaryContext()).start();
            }
        });
        cachedThreadScheduler.execute(new Runnable() {
            @Override
            public void run() {
                ARouter.init(application);
            }
        });

除了初始化这块,ICE_CREAM_SANDWICH以后我们可以通过在Application内注册ActivityLifeCircleCallbak监听activity的生命周期,后面可以了解到Arouter也可以检测到,或者第三种方案就是在Application内维持一个List<Activity> activities,BaseActivity生命周期内去更新这个变量。

  1. BaseActivity 这个作为跨页面控制比较重要的结构,可以封装一些比较常用的方法,这里我主要维护了一个List<Fragment> fragments,用来管理activity下面的fragment,因为当前app主流还是单activity多fragment的模式,还有就是保存一些经常使用的变量,比如Realm,Rxbus还有ioc框架的初始化,这里的ioc我也是自己写的 比较简单,只有click,longclick两个事件Potato
Utils

这个模块就大概讲解下,主要都是一些基本的工具包,各个项目通用,github有提供下载。

Rxbus

类似与EventBus,因为本身我们引入了RxJava,所以用rxjava来实现事件总线是更可取的方法。参考rxbus实现,在post中采用了tag,更符合eventbus的使用习惯,具体就是封装Event包裹了一个tag对用户透明,在返回的时候先filter筛选然后采用flatMap进行转化

MVP

关于mvp模式的实现,中间想了蛮久,主要是纠结于怎样使用范型,在BaseActivity进行P跟V的绑定,以及P跟M的关联,参照了google的mvp实现,使用了contracts使接口或者抽象类更加关系明确,集中。
这里我们实现了BasePresenter<T>这里的T是用来引入M的,而V的引入在BaseActivity<V extends BasePresenter>这样就形成了一个V初试化P,然后P初始化M的链,P就成为了关键,当V destroy的时候就P就解绑V,释放M,把业务逻辑放到P上,插句题外话,中间了解了下mvvm也就是m-vm-v的模式,直接在布局层就将数据跟v通过viewmodel紧密结合了,省掉了findViewById的工作,但个人不太喜欢这种模式,感觉可读性较差,分层不是那么明确

monitor

监视框架,已经引入了blockcanary,leakcanary,接下来要引入aop设计进行关键点检测,然后接入友萌,这个就是中国版的firebase当初去外企面试被问倒了,哈哈哈

test

测试框架还没开始,主要分单元测试,espresso ui测试,mock数据...测试框架蛮多的,最近再看,按顺序来吧

ARouter

路由机制,github上有两个下载量多的,之所一选择ali的完全是信仰吧,基本就是一些配置,使用说明官网有ARouter,采用这种机制也是偶然在android weekly上看到人家一个老司机用这种框架搭建中小型项目,也算是一种新的尝试吧。

2017/3/1:更新Mvp

文章未完待续,尽量月底前完成接下来的工程,欢迎喜欢这文章的朋友下载我的代码,帮我发现问题,完善框架SpaghettiFrame

上一篇下一篇

猜你喜欢

热点阅读