你的位置:首页 > 软件开发 > 操作系统 > 【腾讯Bugly干货分享】基于RxJava的一种MVP实现

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

发布时间:2016-09-02 16:00:05
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57bfef673c1174283d60bac0Dev Club 是一个交流移动开发技术,结交朋友,扩展人脉的社群,成员都是经过审核的移动开发工程师。每周都会举行 ...

本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57bfef673c1174283d60bac0

Dev Club 是一个交流移动开发技术,结交朋友,扩展人脉的社群,成员都是经过审核的移动开发工程师。每周都会举行嘉宾分享,话题讨论等活动。

本期,我们邀请了腾讯IEG Android 开发工程师——戴俊,为大家分享《基于RxJava的一种MVP实现》。

分享内容简介:

RxJava是一个实现Java响应式编程的库,让异步事件以序列的形式组织。MVP则通常用来将View业务层与Model层分离开来,两者结合起来可轻松实现业务解耦、线程控制、单元测试等等强大功能

内容大体框架:

  1. Android开发框架的选择
  2. 如何一步步搭建MVP分层框架
  3. 使用RxJava来进行线程控制
  4. 结语

下面是本期分享内容整理


Hello,大家好,我是戴俊。目前在IEG腾讯动漫主要负责Android端的开发工作。

第一次进行这种微信群的分享,如果有任何疑问,欢迎大家在分享结束后提问。下面开始我们今天的分享。

1. Android开发框架的选择

我们知道原生Android开发已经是一个基础的MVC框架,所以在项目刚开始开发的时候并没有遇到太多问题。

对一个经典的Android MVC框架来讲,它的结构大概是下面这样(图片来自参考文献)

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

这样的结构下,Activity层既承担了View层的一部分工作(因为

拿我们项目早期的例子,一个Activity曾经最多达到了2000到3000行,重构的时候极其痛苦。

要解决这个问题,主要的办法有两种:

  • 第一种是分层
  • 第二种是模块化。

两个方法最终要实现的都是解耦。分层讲的是纵向层面上的解耦,模块化则是横向上的解耦。

我们今天要讨论的MVP就是一种通过分层来进行解耦的框架。

2. 如何一步步搭建MVP分层框架

如果你是个习惯了读文档的老司机,可以直接参考下面几篇文章

  1. Android Application Architecture
  2. Android Architecture Blueprints - Github
  3. Google官方MVP示例之TODO-MVP - 简书
  4. todo-mvp - github
  5. dev-todo-mvp-rxjava - github

当然如果觉得看官方的示例太麻烦,那么下面我们就来讲解一下如何实现一个简单的MVP构架。

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

这是一个比较典型的MVP结构图(图片来自参考文献),相比于第一张图,多了两个层,一个是Presenter和DataManager层。

多出这两个层到底有什么作用,下面我们来用代码说明。

首先我们假设有一个从服务端获取字符串并显示的手机上的简单功能。下面是主界面的代码

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

Activity里面包含了几个文件,一个是View层的对外接口MainView,一个是P层的Presenter。

首先看View层的对外接口文件

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

因为这个功能比较简单,只需要在设备上显示一个字符串,所以只有一个接口方法onShowString(),再看P层代码

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

从上面三个文件可以看到,View层通过注册Listener将自己的接口MainView交给了Presenter, 而Presenter层持有Model层的也只是一个接口。通过Presenter层将业务层与展现层隔离了开来,这样的好处是什么?

我们知道接口的一个作用通常是用来抽象行为,对外部屏蔽实现细节。所以对于View层来说,业务细节被屏蔽了,对业务层来说,展示细节被屏蔽了。而对于处于中间的Presenter层来说,它就像一个接口拼装器,把View层发出的请求传递给业务层,把业务层返回的数据又送还给View层展示,至于前后两端怎么实现的,它才不用关心。

接口的第二个作用是可以用来切换实现。我们先看下面的代码。

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

从上面三个文件可以看到,业务层对外的只有一个接口,实现却有两个(DataSourceImpl和DataSourceTestImpl)。从名字大家就能看出来有什么作用了,一个是正常环境的业务层实现,一个是测试环境的业务层实现。

这里我们设想一个场景:

开发同学接到一个新的需求,设计稿也输出完成了,然而后台的接口却迟迟没到,怎么办? 现在通过MVP,我们把业务层实现切换到DataSourceTestImpl,是不是可以先自己假写数据,调好一切前端和交互,然后泡一杯咖啡等后台同学把接口写完联调?或者有时候为了重现一个bug,要在线上写一条脏数据,测试完再删除?

类似的应用场景其实有非常非常多,这里我们就看到了使用接口解耦的一个好处了,不仅把业务层和展示层解耦开来,还把Android开发同其它的一切的外部数据依赖都解耦开来。

这里我想提到之前讨论过的单元测试问题,很多同学反馈项目开发过程中没有做过,或者没有时间精力去做单元测试,或者因为业务变化太大导致无法做单元测试。其实在我们项目中也遇到过样的问题,但其实通过这样分层之后,才发现单元测试其实是完全可以推进的,也完全不用再担心测试的时候会把脏数据写到线上的问题了。

到现在为止一个基于MVP简单框架就搭建完成了,但其实还遗留了一个比较大的问题。

很多同学可能已经发现了,Presenter层在调用业务层的时候是直接调用的,而Android规定,主线程是无法直接进行网络请求,会抛出NetworkOnMainThreadException异常。

所以在presenter层,我们需要进行一项线程切换的工作,这样才能保证“所有的IO操作都应当在线程中完成,主线程只负责页面渲染的工作”这一优化准则。

当然,Android本身提供一些方案,比如下面这种:

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

通过新建子线程进行IO读写获取数据,然后通过主线程的Looper将结果通过传回主线程进行展示,这种方案是勉强也行得通的。

但问题也有,一是线程需要额外管理,不可能每次发请求都要开启一个线程;二是适应性差,假如数据请求有先后依赖,有并行的情况,这样的写法变得脏乱无比。

好在有了RxJava ,可以比较方便的解决这个问题。

3. 使用RxJava来进行线程控制

RxJava是一个天生用来做异步的工具,相比AsyncTask,Handler等,它的优点就是简洁,无比的简洁。在Android中使用RxJava需要加入下面两个依赖。

 compile 'io.reactivex:rxjava:1.0.14' compile 'io.reactivex:rxandroid:1.0.1'

这里我们直接介绍如何使用RxJava解决这个问题,在presenter中修改方法getData()。

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

简单解释一下,dataAction是我们的数据业务逻辑,viewAction是界面的显示逻辑,通过RxJava的传递和变换,dataAction会在由RxJava管理的IO线程—Schedulers.io() 中执行,而viewAction则会在UI线程—AndroidSchedulers.mainThread()中执行。

RxJava当然不止这么简单,还有别的玩法,比方说进入一个界面的时候,需要先加载缓存的数据,然后再从网络获取更新的数据进行刷新。有的时候,可能还需要处理IO过程中的异常情况,加入RxJava的异常处理参数。

【腾讯Bugly干货分享】基于RxJava的一种MVP实现

RxJava的使用场景远不止这些,线程变换、数据变换、接口顺序依赖、接口并发请求这些要求对它来说都是小菜一碟。当然,有些同学可能觉得RxJava入手有些困难,代码也会变得不那么直观,但相信只要大家慢慢熟悉它之后,它就会变得无比讨人喜欢。

下面列出了一些常见的RxJava的常用场景,其实还有更多的其它功能等待着大家去挖掘。

  1. 取数据先检查缓存的场景
  2. 需要等到多个接口并发取完数据,再更新
  3. 一个接口的请求依赖另一个API请求返回的数据
  4. 界面按钮需要防止连续点击的情况
  5. 响应式的界面
  6. 复杂的数据变换

上面这些功能都可以通过RxJava来轻松完成。具体的使用就不再多讲了,大家可以参考下面的文章:(Google文章名就可以了)

1.给 Android 开发者的 RxJava 详解

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:【腾讯Bugly干货分享】基于RxJava的一种MVP实现

关键词:JAVA

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。