你的位置:首页 > 软件开发 > 操作系统 > 【腾讯Bugly干货分享】一步一步实现Android的MVP框架

【腾讯Bugly干货分享】一步一步实现Android的MVP框架

发布时间:2016-07-28 20:00:07
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5799d7844bef22a823b3ad44内容大纲:Android 开发框架的选择如何一步步搭建分层框架使用 RxJava 来解决主线程发出网络请求的问题结 ...

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

内容大纲:

  1. Android 开发框架的选择
  2. 如何一步步搭建分层框架
  3. 使用 RxJava 来解决主线程发出网络请求的问题
  4. 结语

    一、Android开发框架的选择

    由于原生 Android 开发应该已经是一个基础的 MVC 框架,所以在初始开发的时候并没有遇到太多框架上的问题,可是一旦项目规模到了一定的程度,就需要对整个项目的代码结构做一个总体上的规划,最终的目的是使代码可读,维护性好,方便测试。’

    只有项目复杂度到了一定程度才需要使用一些更灵活的框架或者结构,简单来说,写个 Hello World 并不需要任何第三方的框架

    原生的 MVC 框架遇到大规模的应用,就会变得代码难读,不好维护,无法测试的囧境。因此,Android 开发方面也有很多对应的框架来解决这些问题。

    构建框架的最终目的是增强项目代码的可读性维护性方便测试 ,如果背离了这个初衷,为了使用而使用,最终是得不偿失的

    从根本上来讲,要解决上述的三个问题,核心思想无非两种:一个是分层 ,一个是模块化 。两个方法最终要实现的就是解耦,分层讲的是纵向层面上的解耦,模块化则是横向上的解耦。下面我们来详细讨论一下 Android 开发如何实现不同层面上的解耦。

    解耦的常用方法有两种:分层模块化

    横向的模块化对大家来可能并不陌生,在一个项目建立项目文件夹的时候就会遇到这个问题,通常的做法是将相同功能的模块放到同一个目录下,更复杂的,可以通过插件化来实现功能的分离与加载。

    纵向的分层,不同的项目可能就有不同的分法,并且随着项目的复杂度变大,层次可能越来越多。

    对于经典的 Android MVC 框架来说,如果只是简单的应用,业务逻辑写到 Activity 下面并无太多问题,但一旦业务逐渐变得复杂起来,每个页面之间有不同的数据交互和业务交流时,activity 的代码就会急剧膨胀,代码就会变得可读性,维护性很差。

    所以这里我们就要介绍 Android 官方推荐的 MVP 框架,看看 MVP 是如何将 Android 项目层层分解。

    二、如何一步步搭建分层框架

    如果你是个老司机,可以直接参考下面几篇文章(可在 google 搜到):

  5. Android Application Architecture

  6. Android Architecture Blueprints - Github
  7. Google 官方 MVP 示例之 TODO-MVP - 简书
  8. 官方示例1-todo-mvp - github
  9. dev-todo-mvp-rxjava - github

    当然如果你觉得看官方的示例太麻烦,那么本文会通过最简洁的语言来讲解如何通过 MVP 来实现一个合适的业务分层。

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

    【腾讯Bugly干货分享】一步一步实现Android的MVP框架

    简单来讲,就是 Activity 或者 Fragment 直接与数据层交互,activity 通过 apiProvider 进行网络访问,或者通过 CacheProvider 读取本地缓存,然后在返回或者回调里对 Activity 的界面进行响应刷新。

    这样的结构在初期看来没什么问题,甚至可以很快的开发出来一个展示功能,但是业务一旦变得复杂了怎么办?

    我们作一个设想,假如一次数据访问可能需要同时访问 api 和 cache,或者一次数据请求需要请求两次 api。对于 activity 来说,它既与界面的展示,事件等有关系,又与业务数据层有着直接的关系,无疑 activity 层会极剧膨胀,变得极难阅读和维护。

    在这种结构下, activity 同时承担了 view 层和 controller 层的工作,所以我们需要给 activity 减负

    所以,我们来看看 MVP 是如何做这项工作的(图片来自参考文献)

    【腾讯Bugly干货分享】一步一步实现Android的MVP框架

    这是一个比较典型的 MVP 结构图,相比于第一张图,多了两个层,一个是 Presenter 和 DataManager 层。

    所谓自古图片留不住,总是代码得人心。下面用代码来说明这个结构的实现。

    首先是 View 层的 Activity,假设有一个最简单的从 Preference 中获取字符串的界面

    public class MainActivity extends Activity implements MainView { MainPresenter presenter; TextView mShowTxt; @Override protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.activity_main);   mShowTxt = (TextView)findViewById(R.id.text1);   loadDatas(); } public void loadDatas() {   presenter = new MainPresenter();   presenter.addTaskListener(this);   presenter.getString(); } @Override public void onShowString(String str) {   mShowTxt.setText(str); }}

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

    首先对外接口 MainView 文件

    public interface MainView { void onShowString(String json);}

    因为这个界面比较简单,只需要在界面上显示一个字符串,所以只有一个接口 onShowString,再看P层代码

    public class MainPresenter { MainView mainView; TaskManager taskData; public MainPresenter() {   this.taskData = new TaskManager(new TaskDataSourceImpl()); } public MainPresenter test() {   this.taskData = new TaskManager(new TaskDataSourceTestImpl());   return this; } public MainPresenter addTaskListener(MainView viewListener) {   this.mainView = viewListener;   return this; } public void getString() {   String str = taskData.getTaskName();   mainView.onShowString(str); }}

    可以看到 Presenter 层是连接 Model 层和 View 层的中间层,因此持有 View 层的接口和 Model 层的接口。这里就可以看到 MVP 框架的威力了,通过接口的形式将 View 层和 Model 层完全隔离开来。

    接口的作用类似给层与层之间制定的一种通信协议,两个不同的层级相互交流,只要遵守这些协议即可,并不需要知道具体的实现是怎样

    看到这里,有人可能就要问,这跟直接调用有什么区别,为什么要大费周章的给 view 层和 Model 层各设置一个接口呢?具体原因,我们看看 Model 层的实现类就知道了。

    下面这个文件是 DataManager.java,对应的是图中的 DataManager 模块

    /*** 从数据层获取的数据,在这里进行拼装和组合*/public class TaskManager { TaskDataSource dataSource; public TaskManager(TaskDataSource dataSource) {   this.dataSource = dataSource; } public String getShowContent() {   //Todo what you want do on the original data   return dataSource.getStringFromRemote() + dataSource.getStringFromCache(); }}

    TaskDataSource.java 文件

    /*** data 层接口定义*/public interface TaskDataSource { String getStringFromRemote(); String getStringFromCache();}

    TaskDataSourceImpl.java 文件

    public class TaskDataSourceImpl implements TaskDataSource { @Override public String getStringFromRemote() {   return "Hello "; } @Override public String getStringFromCache() {   return "World"; }}

    TaskDataSourceTestImpl.java 文件

    public class TaskDataSourceTestImpl implements TaskDataSource { @Override public String getStringFromRemote() {   return "Hello "; } @Override public String getStringFromCache() {   return " world Test "; }}

    从上面几个文件来看, TaskDataSource.java 作为数据层对外的接口, TaskDataSourceImpl.java 是数据层,直接负责数据获取,无论是从api获得,还是从本地数据库读取数据,本质上都是IO操作。 TaskManager 是作为业务层,对获取到的数据进行拼装,然后交给调用层。

    这里我们来看看分层的作用

    首先来讲业务层 TaskManager,业务层的上层是 View 层,下层是 Data 层。在这个类里,只有一个 Data 层的接口,所以业务层是不关心数据是如何取得,只需要通过接口获得数据之后,对原始的数据进行组合和拼装。因为完全与其上层和下层分离,所以我们在测试的时候,可以完全独立的是去测试业务层的逻辑。

    TaskManager 中的 construct 方法的参数是数据层接口,这意味着我们可以给业务层注入不同的数据层实现。

    原标题:【腾讯Bugly干货分享】一步一步实现Android的MVP框架

    关键词:Android

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

可能感兴趣文章

我的浏览记录