所谓MVP(Model-View-Presenter)模式。是将APP的结构分为三层:

view - UI显示层

view 层主要负责:

  1. 提供UI交互
  2. 在presenter的控制下修改UI。
  3. 将业务事件交由presenter处理。
    注意. View层不存储数据,不与Model层交互。

presenter - 逻辑处理层

presenter 层主要负责:

  1. 对UI的各种业务事件进行相应处理。也许是与Model层交互,也许自己进行一些计算,也许控制后台Task,Servic
  2. 对各种订阅事件进行响应,修改UI。
  3. 临时存储页面相关数据。
    注意. Presenter内不出现View引用。

model - 数据层

model层主要负责:

  1. 从网络,数据库,文件,传感器,第三方等数据源读写数据。
  2. 对外部的数据类型进行解析转换为APP内部数据交由上层处理。
  3. 对数据的临时存储,管理,协调上层数据请求。

如图示,里面的activity,presenter,model均为例子:

mvp

将复杂的功能分割为各层内的小问题。各层内功能单一。这样易于功能修改拓展与Debug。
解耦的设计,独立的模块,更有利于分工开发与测试。

Activity的异常重启

Activity会在少数情况下被系统重启:

当用户旋转屏幕
在后台时内存不足
改变语言设置
attache 一个外部显示器等。

正确的方式应该是:
Presenter与Activity的绑定关系应由静态类管理。而不是由Activity管理。当Activity意外重启时Presenter不应重启。Activity重启时,Presenter与Activity重新绑定,根据数据恢复Activity状态。
而当Activity真正销毁时。对应Presenter才应该跟随销毁。

当内存不足时,Activity被销毁其实是整个进程被销毁。所以Presenter也无能为力。还原时需要重建Presenter。

生命周期

Activity是一个上帝类,其实不适合作为View。所以有些MVP方案将Activity作为Presenter。最主要在于他的生命周期牵扯太多逻辑处理业务。这些由Presenter负责的话情况可以改善很多。我建议将在顶级父类中将activity的生命周期在Presenter中实现一遍,然后生命周期有关的业务逻辑直接由Presenter来实现。

Model的初始化

Model不仅仅是javabean。Model是负责提供各类数据模型。在此基础上我将Model拓展为数据层提供数据交互。将javabean单独为数据层的一部分。
Model层的各个Model一般使用单例。这样的好处在于这个唯一对象可以管理一些数据供所有上层使用。
Model的单例对象

public class UserModel extends AbsModel{
public static UserModel getInstance() {
return getInstance(UserModel.class);
}
@Override
protected void onAppCreate(Context ctx) {
super.onAppCreate(ctx);
//初始化
} public void login(String number,String password,DataCallback<UserDetail> callback){
//进行登录请求与回调,并保存返回账号
}
public void register(String tel,String password,String code,int gender,String nickname,StatusCallback callback){
//进行注册请求与回调
} public void findPassword(String number,String code,String password,DataCallback<User> callback){
//进行找回密码请求与回调
} public void certification(String number,String school,String realName,String stuCard,DataCallback<User> callback){
//进行认证请求与回调
} public void LoginOut(){
//登出操作
} }

既然Model层管理数据,并且是单例。他就有初始化的需求,比如在APP启动时就请求数据,记录信息,开始一个后台线程与服务器同步信息等。这些操作与Presenter无关。是数据层自发的的功能。所以需要在Application启动时进行Model的初始化。
但又要注意不能在Application的onCreate()进行过多操作,否则会启动时间过长。所以可考虑在启动时创建一个后台线程,将即时性不强的初始化操作放到后台线程。

Adapter的处理

对于Adapter是放在View好还是Presenter好,这个问题确实难以解决。但在使用解耦的ViewHolder后这个问题便很明了。视图的创建与改变全由ViewHolder管理。然后Adapter仅仅处理面向ViewHolder的逻辑。
然后ViewHolder属于View,Adapter属于Presenter。参考EasyRecyclerView
Adapter:

public class PersonAdapter extends RecyclerArrayAdapter<Person> {
public PersonAdapter(Context context) {
super(context);
} @Override
public BaseViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) {
return new PersonViewHolder(parent);
}
}

ViewHolder:

public class PersonViewHolder extends BaseViewHolder<Person> {
private TextView mTv_name;
private SimpleDraweeView mImg_face;
private TextView mTv_sign; public PersonViewHolder(ViewGroup parent) {
super(parent,R.layout.item_person);
mTv_name = $(R.id.person_name);
mTv_sign = $(R.id.person_sign);
mImg_face = $(R.id.person_face);
} @Override
public void setData(final Person person){
mTv_name.setText(person.getName());
mTv_sign.setText(person.getSign());
mImg_face.setImageURI(Uri.parse(person.getFace()));
}
}

Rx的参与

Rx订阅发布模式在MVP中作用很大。可以极大简化层间通讯的处理。View向Presenter订阅数据。Presenter可以向Model层订阅数据。形成一个数据链。数据可以直接链式到达View层。优雅易拓展。
Presenter

public class QuestionShowPresenter extends BeamDataActivityPresenter<QuestionShowActivity,Question> {

    @Override
protected void onCreate(QuestionShowActivity view, Bundle savedState) {
super.onCreate(view, savedState);
QuestionModel.getInstance().getQuestion(1).subscribe(this);
}
}

View

public class QuestionShowActivity extends BeamDataActivity<QuestionShowPresenter,Question> {
@Override
public void setData(Question data) {
//显示数据
} @Override
public void setError(Throwable e) {
//显示错误
}
}

Beam

Beam是我做的一套基于MVP模式的快速开发框架。参考了nucleus。上面的示例代码都是使用了这个(为方便复制的这个框架demo代码.= =)。定义了一套开发规范。并提供了基于这套规范的Activity,Fragment,Presenter,Model等父类及控件和API等,完成APP开发过程中大量繁琐工作。并进行了一系列优化。详情看这里

文/Jude95(简书作者)
原文链接:http://www.jianshu.com/p/ed2aa9546c2c
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

Android应用中MVP开发模式的更多相关文章

  1. 理解 Android MVP 开发模式

    /***************************************************************************************** * 理解 Andr ...

  2. Android MVP开发模式及Retrofit + RxJava封装

    代码已上传到Github,因为接口都是模拟无法进行测试,明白大概的逻辑就行了! 欢迎浏览我的博客--https://pushy.site 1. MVP模式 1.1 介绍 如果熟悉MVP模式架构的话,对 ...

  3. C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例

    C# 动态生成word文档 本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正. 在工程中引用word的动态库 在项目中,点击项目名称右键-- ...

  4. [译]Google官方关于Android架构中MVP模式的示例

    概述 该示例(TODO-MVP)是后续各种示例演变的基础,它主要演示了在不带架构性框架的情况下实现M-V-P模式.其采用手动依赖注入的方式来提供本地数据源和远程数据源仓库.异步任务通过回调处理. 注意 ...

  5. Google官方关于Android架构中MVP模式的示例续-DataBinding

    基于前面的TODO示例,使用Data Binding库来显示数据并绑定UI元素的响应动作. 这个示例并未严格遵循 Model-View-ViewModel 或 Model-View-Presenter ...

  6. Android应用中MVP最佳实践

    转自:http://www.jianshu.com/p/ed2aa9546c2c 文/Jude95(简书作者)原文链接:http://www.jianshu.com/p/ed2aa9546c2c著作权 ...

  7. IOS 与ANDROID框架及应用开发模式对照一

    IOS 和ANDROID操作系统都是眼下流行的移动操作系统,被移动终端和智能设备大量採用,两者都採用了先进的软件技术进行设计,为了方便应用开发两者都採用了先进的设计模式. 两者在框架设计上都採用了什么 ...

  8. IOS 与ANDROID框架及应用开发模式对比一

    IOS 和ANDROID操作系统都是目前流行的移动操作系统,被移动终端和智能设备大量采用,两者都采用了先进的软件技术进行设计,为了方便应用开发两者都采用了先进的设计模式.两者在框架设计上都采用了什么技 ...

  9. Asp.net MVC 中 CodeFirst 开发模式实例

    昨天写的这篇博客因为下班时间到了忘记保存了,好郁闷,得重新写一遍.实习所在公司使用的是CodeFirst开发模式,最近开始参与到公司的项目里面来了,发现这个模式特别好用,建库建表改变字段属性添加删除字 ...

随机推荐

  1. 缓存Cache

    转载自  博客futan 这篇文章将全面介绍有关 缓存 ( 互动百科 | 维基百科 )cache以及利用PHP写缓存caching的技术. 什么是缓存Cache? 为什么人们要使用它? 缓存 Cach ...

  2. ios web html 上传图片到服务器后方向不对解决

    结论: 1.ios上传会在exif中带一个 Orientation的属性,这个属性在windows中不会生效,在ios浏览器中会生效,造成图片在windows资源管理器中与ios浏览器中方向不一致 2 ...

  3. python 列表排序

    转自http://www.iplaypython.com/jinjie/jj114.html reverse()方法 将列表中元素反转排序,比如下面这样>>> x = [1,5,2, ...

  4. mysql优化一 之 优化内容概述及开启慢查日志的相关配置

    1-1数据库优化的目的 首先是为了避免出现页面访问错误(基本有三种) (1)由于数据库连接timeout产生的页面5XX错误 (2)由于慢查询造成页面无法加载 (3)由于阻塞造成的数据无法提交 其次: ...

  5. Cenots7编译Opencv3.1错误:下载ippicv,解决方案

    在centos7上安装Opencv的时候,停在了下载ippicv的地方,一直都下载不下来. ippicv是一个并行计算库,其实可以不用的. 如果不想用这个并行计算库,在做Cmake的时候用参数关闭即可 ...

  6. Android 进程常驻----开机广播的简单守护以及总结

    这是一个轻量级的库,配置几行代码,就可以实现在Android上实现进程常驻,也就是在系统强杀下,以及360获取root权限下,clean master获取root权限下都无法杀死进程 支持系统2.3到 ...

  7. WPF 中 InitializeComponent 不存在解决方案

    部门给了一个WPF应用,但是之前没学过,所以再用vs2015创建测试程序的时候,竟然报了错,一创建项目就报错的程序还真不多.大概就是 InitializeComponent不存在吧.所以在网上看了很多 ...

  8. [poj2411] Mondriaan's Dream (状压DP)

    状压DP Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One nigh ...

  9. Python3基础 访问列表 大于等于指定索引值的所有元素

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  10. Linux帮助命令

    帮助命令:man man 命令 获取命令的帮助 如下: [root@localhost ~]# man ls LS(1) User Commands LS(1) NAME ls - list dire ...