说来羞愧,MVP的架构模式已经在Android领域出现一两年了。可是到今天自己才開始Android领域中的MVP架构征程。

闲话不多说,開始吧。

一、架构演变概述

我记得我找第一份工作时,面试官问我“android是否属于MVC架构模式,简述一下”。确实,Android的总体设计结构就是MVC的设计模式。在J2EE的开发中,使用的也是MVC模式,MVC模式是一个经典,经历了几十年的考验。Android项目中的MVC架构:

  • View:是应用程序中处理数据显示的部分。相应于layout文件下的布局文件
  • Model:业务逻辑和实体模型
  • Controllor:是应用程序中处理用户交互的部分。Activity来充当。

看似分工明白,可是也给我们带来了不少问题,假设一个页面的业务逻辑很复杂,我们的Activty须要大量的逻辑处理代码,使得Activity既像View又像Controllor,又当爹又当妈。工作量很大。

造成代码的阅读星很差。

为了解决问题。MVP模式就在Android领域诞生了。补充:我查看资料发现MVP模式最早是微软设计出来的,应用在Visual Stuido平台,不得不说微软尽管闭源,可是很niubility。

二、MVP概述

上面的图。精炼的概述了MVP架构之间的通讯流程。在android中。

  • 模型(Model):业务逻辑处理,负责处理数据的载入或者存储,比方从网络或本地数据库获取数据等。
  • 视图(View):负责界面数据的展示,与用户进行交互,就是Activity。
  • 主导器(Presenter):相当于协调者。是模型与视图之间的桥梁。将模型与视图分离开来。通过Presenter进行它们之间的交互,隔离了M、V之间的直接交互。

这种架构。就让我们的Activity更像View,减少了M、V之间的耦合度。

三、MVP实践

我们先看下我们的效果图:

这是一个简答的登陆页面,在这个登陆页面中,我们就触发一个事件,就是点击登陆事件。我们先看看我们的project组织架构。

我们分别创建了:bean、model、presenter、view四个包。为了解放Activity,我们把曾经Activity里的大量逻辑进行拆分。

1、bean包

我们创建实体UserBean,用来存放我们的用户信息。这个没什么说的。

    public class UserBean implements Parcelable{
private String name;
private String password; public UserBean(){ } public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} @Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(password);
}
}

2、view包

我们首先从View(视图层)看,view包下存放了我们视图层中的操作,它不涉及不论什么业务逻辑。主要是针对我们的页面进行数据的获取与设置

我们针对这个登陆功能。进行分析:

  • 姓名和密码的获取
  • 姓名和密码的保存

我们抽取出页面View层须要做的事情。接下来我们定义一个IUserView接口,里面包括我们抽取出来的方法。

    /**
* 抽离View层。用于View页面的数据获取之类
* @author Administrator
*
*/
public interface IUserView {
public String getUserName();
public String getUserPsd();
}

我们仅仅进行了获取,没有做保存。总结:View层的任务就是抽象页面的数据,提取出来写成方法。

3、model包

在view层,我们的数据获取有了着落,如今我们就開始处理我们的业务逻辑。依据页面得知,我们就模拟一个登陆功能。所以它就一个登陆事件。

我们创建IUserModel接口用于包括我们处理的业务逻辑。

    /**
* 业务逻辑处理
* @author Administrator
*
*/
public interface IUserModel {
/**
*提取的一个登陆方法。当然还能够有其他方法。比方获取数据,保存用户信息之类
* @param name username
* @param pwd 密码
* @param loginListener 登陆监听
*/
public void login(String name,String pwd,ILoginListener loginListener);
}

有了业务逻辑的接口规范。我们还须要去实现它,给与我们想要的逻辑。所以就有了UserModel类:

    public class UserModel implements IUserModel{

        @Override
public void login(String name, String pwd, ILoginListener loginListener) {
if(TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)){
loginListener.onError();
return;
} try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if("dsw".equals(name) && "123".equals(pwd)){
loginListener.onSucess();
}else{
loginListener.onFail();
}
}
}

我们为了方便我们对业务逻辑处理的监听,所以我们创建了一个接口,用来推断我们的登陆事件。

    /**
* 登陆接口的监听,方便我们在View层中控制,便于给出提示
* @author Administrator
*
*/
public interface ILoginListener {
//登陆成功
public void onSucess();
//登陆失败
public void onFail();
//数据不完毕
public void onError();
}

我们用来监听业务处理的推断。比方成功了我们弹出一个Toast之类的。

4、presenter包

数据有了,对数据的业务处理也有了。这里我们的Presenter就闪灵登场了。记住是Presenter、Presenter、Presenter(重要的东西说三次)。它用来连接我们的M、V层,让二者打通任督二脉实现整个流程。所以为了实现二者的联系。它的内部必定会有M、V的实例。来看看IUserPresenter:

    public class IUserPresenter {
//数据源
private IUserView userView;
//处理业务逻辑
private IUserModel userModel; public IUserPresenter(IUserView userView){
this.userView = userView;
userModel = new UserModel();
} /**
* 登陆方法。进行M,V层的关系建立
* @param loginListener
*/
public void login(ILoginListener loginListener){
userModel.login(userView.getUserName(), userView.getUserPsd(), loginListener);
}
}

我们仅仅须要在Activity中创建一个IUserPresenter类,然后调用login方法进行登录就可以。

在这段代码中。IUserView是我们的数据源,我们通过它的方法用于从页面获取数据,所以我们的Activity必须实现这个IUserView接口,然后传递给IUserPresenter。在IUserPresenter中调用IUserModel的实现业务逻辑的处理。

5、最后的Activity处理

    public class MainActivity extends Activity implements IUserView {
private EditText et_name,et_pwd;
private Button btn_login;
//指示器与View层进行交互
private IUserPresenter userPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name = (EditText) findViewById(R.id.et_name);
et_pwd = (EditText) findViewById(R.id.et_psw);
btn_login = (Button) findViewById(R.id.btn_login);
userPresenter = new IUserPresenter(this);
btn_login.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
userPresenter.login(loginListener);
}
});
}
@Override
public String getUserName() {
return et_name.getText().toString();
}
@Override
public String getUserPsd() {
return et_pwd.getText().toString();
} /**
* 登陆监听接口
*/
private ILoginListener loginListener = new ILoginListener() { @Override
public void onSucess() {
Toast.makeText(getApplication(), "登陆成功", Toast.LENGTH_SHORT).show();
} @Override
public void onFail() {
Toast.makeText(getApplication(), "登陆失败", Toast.LENGTH_SHORT).show();
} @Override
public void onError() {
Toast.makeText(getApplication(), "数据不完整,请又一次输入", Toast.LENGTH_SHORT).show();
}
};
}

在activity中,我们实现IUserView接口,来实现该view层的数据获取。

然后创建IUserPresenter类。调用login方法进行登录。同一时候实现对业务逻辑的处理监听。

至此。我们就完毕了整个的流程。看看我们的效果图:

源代码本来打算上传的熬csdn的,结果上传不了,所以果断github

强烈建议大家手动敲一遍代码,加深理解。

总结图:

==========================================================

作者:mr_dsw

转载注明出处,分享是进步的源泉。

==========================================================

Android中的MVP架构初探的更多相关文章

  1. Android中的MVP架构分解和实现

    1.概述 传统的Android开发架构通常是MVC模式. Model:业务逻辑和实体模型 View:相应于布局文件 Controllor:相应于Activity 单独从逻辑看起来很好,与我们做Web开 ...

  2. 转:Android开发中的MVP架构(最后链接资源不错)

    Android开发中的MVP架构 最近越来越多的人开始谈论架构.我周围的同事和工程师也是如此.尽管我还不是特别深入理解MVP和DDD,但是我们的新项目还是决定通过MVP来构建. 这篇文章是我通过研究和 ...

  3. 转: Android开发中的MVP架构详解(附加链接比较不错)

    转: http://www.codeceo.com/article/android-mvp-artch.html 最近越来越多的人开始谈论架构.我周围的同事和工程师也是如此.尽管我还不是特别深入理解M ...

  4. 设计模式笔记之二:Android开发中的MVP架构(转)

    写在前面,本博客来源于公众号文章:http://mp.weixin.qq.com/s?__biz=MzA3MDMyMjkzNg==&mid=402435540&idx=1&sn ...

  5. Android 中的MVP 模式

    MVP模式的核心思想: MVP把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成功接口,Model类还是原来的Model. MVC 其中View层其实就是程序的UI界面,用于向用户展示 ...

  6. android中的MVP模式

    1.建立bean public class UserBean { private String mFirstName; private String mLastName; public UserBea ...

  7. Android中的四层架构,五块区域

    1. Linux内核层Android系统是基于Linux 2.6内核的,这一层为Android设备的各种硬件提供了底层的驱动,如显示驱动.音频驱动.照相机驱动.蓝牙驱动.Wi-Fi驱动.电源管理等.2 ...

  8. android sensor传感器系统架构初探

    http://blog.csdn.net/qianjin0703/article/details/5942579 http://blog.chinaunix.net/uid-28621021-id-3 ...

  9. ReadHub项目Kotlin版开发指南(三、MVP架构)

    ReadHub项目Kotlin版转换指南(一.环境搭建) ReadHub项目Kotlin版转换指南(二.数据库和网络请求) ReadHub项目Kotlin版转换指南(三.MVP架构) Android ...

随机推荐

  1. write---向指定登录用户终端上发送信息

    write命令用于向指定登录用户终端上发送信息.通过write命令可传递信息给另一位登入系统的用户,当输入完毕后,键入EOF表示信息结束,write命令就会将信息传给对方.如果接收信息的用户不只登入本 ...

  2. 洛谷 P1071 潜伏者

    P1071 潜伏者 题目描述 R 国和 S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动.历尽艰险后,潜伏于 S 国的 R 国间谍小 C 终于摸清了 S 国军用密码的编码规则: 1. S ...

  3. MethodFilterInterceptor(方法拦截器)配置excludeMethors

    由于该类有setExcludeMethods方法,因此在xml中可以配置一个excludeMethods参数 刚开始老是拦截不成功,tomcat显示这个参数没找到,后来终于找到错误:不应该在拦截器栈中 ...

  4. ArcSDE学习笔记------了解ArcSDE

    刚来公司的时候一直在做地图服务,用的是ArcGIS,然后对地图的操作用的是普通的数据库操作.后来带我的一个同事让我学习一下ArcSDE.那么ArcSDE到底是什么呢?明明所有的操作我用普通数据库也实现 ...

  5. Qt之图形(绘制文本)

    简述 前面我们讲解了Qt图形的基本绘制,其中包括: 绘制文本.直线.直线.矩形.弧线.椭圆.多边形.图片,以及其它一些高级用法,比如:渐变.转换等. 本节我们来详细讲解文字的绘制.主要通过QPaint ...

  6. 已知二叉树的中序序列为DBGEAFC,后序序列为DGEBFCA,给出相应的二叉树

    面对这种问题时我们该怎么解决? 今天写数据结构题.发现了一道总是碰见问题的题在这里我写了一种求解方法我自己称它为分层递归求解. 第一步通过观察我们知道后序遍历时最后一个是根节点A 在中序序列中A的左边 ...

  7. C++windows内核编程笔记day11 win32静态库和动态库的使用

    windows库程序: 静态库: 源码被链接到调用的程序或动态库,被调用时,代码最少有1份,文件后缀.LIB 动态库: 函数被程序或其它动态库调用,被调用时,代码仅仅有1份,文件后缀.DLL 静态库( ...

  8. 线程池系列二:ThreadPoolExecutor讲解

    一.简介 1)线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, i ...

  9. FSM之三--代码风格

    FSM设计之一http://www.cnblogs.com/qiweiwang/archive/2010/11/28/1890244.html Moore型状态机与mealy型状态机相比,由于其状态输 ...

  10. oh-my-zsh upgrade problem

    Oh-My-ZSH upgrade issue with bad substitution message   Any problem with automatic Oh-My-Zsh upgrade ...