MVP-Dagger2-Rxjava2

Introduction: 使用 Dagger,LiveData,ViewModel,Rxjava ,Retrofit 等搭建 App 业务模块组件化框架。并处理多个系统提供数据导致的返回数据格式不一致,More ,please readme
More: Author   ReportBugs   
Tags:

请 clone 过老项目的同学也删除

新 Repo 代码 GitHub 链接点这里

使用 Dagger ,Rxjava ,LiveData,ViewModel 等搭建 App 框架

根据项目中出现的工程问题以及平衡业务需求,重构希望能把关注点集中到代码结构、整体架构、可测试性、可维护性以及快速迭代这四个方面。本次迭代除了使用 Dagger,Rxjava,Retrofit,Greendao 等外,新引入了 Google 官方 JetPack 组件中的 LiveData,ViewModel,LifeCycle,WorkManger 等。并把工程框架变为模块化,独立的业务模块可以单独的进行调试,管理。

项目的框架图如下

项目的框架图

项目框架图如上图所示,这里约定一个称谓:Main,News 可以单独依赖 Base 调试,App 壳工程也可以把他们打包集合到一起调试,我们称为 App 模块化架构。如下图切换后 Sync 一下工程 切换模块化开发模式.png

这样的好处是 1.Base 可以在同一公司的多个项目共用 2.负责 Main,New 业务的开发可以只关注自身的 git 权限管理,编译调试(大大减少带薪 Build 时间) 3.工程框架清晰,更容易维护

ViewModel+LiveData 的封装处理

ViewModel 和 LiveData 官方 Jetpack 组件重要组成部分。

  • ViewModel 当因系统配置发生改变导致 Activity 重建的时候(比如旋转屏幕,更改系统语言),能对 LiveData 进行正确的保存和恢复(当然这要配合 LiveData)。当然如果是系统资源紧张被清除是不能恢复的。
  • LiveData 的作用是在使得数据能具有生命周期感知能力,在 Activity 等变为活跃状态的时候,自动回调观察者中的回调方法,也就是说对数据的变化进行实时监听。这样就不会出现异步请求数据成功后 UI 不活跃的时候出现空指针异常,也可以很好的避免内存泄露

但是 onChange 观察回调官方只是处理成功数据的回调,我们需要封装StateLiveData处理网络错误,服务器自定义的一些返回码等情况

        //LiveData 具有生命周期感知能力,它会自动对这些进行管理
        //UI 组件只需要对相关的数据进行监听,不需要关心是否应该暂停或者恢复监听。 
        blogViewModel.getAllBlog().observe(this, stateData -> {
            switch (stateData.getStatus()) {
                case SUCCESS:
                    disposeSuccessData(stateData.getData());
                    break;
                case ERROR:
                    disposeErrorMsg(stateData.getMsg())
                    break;
            }
        });

权侵删

而使用 Retrofit 请求网络业务层的写法也是非常的精简

    public StateLiveData<HotNewsResult> getStateLiveData() {
        //1.异步加载网络请求数据
        newsApiService.getNews()
                .compose(SwitchSchedulers.applyScheduler2())//rxjava 切换线程
                .subscribe(new HttpObserver<NewsResult>() {
                    @Override
                    public void onSuccess(NewsResult newsResult) {
                        stateLiveData.postSuccess(newsResult);
                    }

                    @Override
                    public void onFailure(int code, String message) {
                        super.onFailure(code, message);
                        //把错误信息告知给 UI 操作层面
                        stateLiveData.postFailure(message + code);
                    }
                });
        return stateLiveData;
    }

Dagger 和 ViewModel 结合遇到的问题

项目使用的是 Dagger2 和 Dagger.android,在 Demo 工程中看起来很繁琐,代码量也很多,但是配置好了一劳永逸) 。随着项目业务变多的时候 dagger 相关的代码不会变多,但是能让业务代码化繁为简并解耦。

但是 Dagger 和 ViewModel 结合的时候会有点麻烦。定义好 ViewModelKey 和 class MyViewModelFactory implements ViewModelProvider.Factory 后,其实 和在一个 Activity/Fragment 中使用 Dagger 差不多。

关于多个系统提供数据(多 BaseUrl),返回的 json 数据格式还不一样的情况处理

很多 App 都是多个 BaseUrl,数据由不同的系统提示,甚至内部 Python 和 Java 后台返回的数据 json 格式还不一样,那就要抽象 Base 出来了,demo 的 Blog 和 News 演示了这一情况

Retrofit 全局屏蔽重复请求

应该没有比 Retrofit2 更好的了吧?不过 api 不是 restful 就需要再封装一下了,网路模块就是数据命脉,做好了 整个 app 的结构会简化很多,结合 Rxjava2 更能简化很多。假如点击一个按钮请求数据除了从源头防止还能不能从发起请求的时候检查。

数据的持久化

SP ORMDB (Room,GreenDao,xx)

项目中包含的基本的通用模块

  • Dagger.android 大大的优化 Dagger 在 android 中的使用,
  • BaseActivity 中 Toolbar 的处理
  • 进行网络请求时候的 Error,empty,Loading,timeout 等通用场景处理,Demo 中一处 Root 注入,处处可用
  • Http (Rxjava2+Retrofit2)的闭环处理
  • 聚合型 API 处理(从不同的系统获取数据,返回的 API 结构不同,详细见 thirdParty 包下的处理)
  • 封装 StateLiveData 以便处理失败和业务异常
  • dagger 和 ViewModel 的结合处理

希望大家会喜欢,并在GitHub提出宝贵意见

参考资料:

  • [1]. Google 应用架构指南
  • [2]. LiveData ViewModel Overview
  • [3]. Dagger - A fast dependency injector for Android and Java
  • [4]. Android Jetpack 使用入门 ... ...
Apps
About Me
Google+: Trinea trinea
GitHub: Trinea