说来羞愧,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. 【IDEA】Error: java: Compliance level '1.6' is incompatible with target level '1.8'. A compliance level '1.8' or better is required解决办法

    在运行的时候常常出现如下错误: Error: java: Compliance level '1.6' is incompatible with target level '1.8'. A compl ...

  2. Java代码规范文档

    NOTE:以下部分为一个简要的编码规范,更多规范请参考 ORACLE 官方文档. 地址:http://www.oracle.com/technetwork/java/codeconventions-1 ...

  3. ArcGIS api for javascript——查询,然后单击显示信息窗口

    描述 本例展示如何配置查询任务为示例的工作流程: 1.用户单击一个要素来加亮显示. 2.用户再一次单击要素来查看属性信息的 InfoWindow. 本例查询USA州,因此ESRI_StateCityH ...

  4. [Recompose] Refactor React Render Props to Streaming Props with RxJS and Recompose

    This lesson takes the concept of render props and migrates it over to streaming props by keeping the ...

  5. Android设置背景图片平铺

    以LinearLayout为例,它提供的background属性将会将背景图片拉伸,相当难看.其实我们仅仅需做少量的改动就能够实现web编程中css背景图片的效果.来试试吧. 创建反复的背景图片 在d ...

  6. vue-router学习例子分享

    http://blog.csdn.net/bboyjoe/article/details/52804988 <!DOCTYPE html> <html lang="en&q ...

  7. SQL一列的合并连起来

    CREATE TABLE #temp( ID INT, name NVARCHAR(max), age int, address ) ) insert into #temp select ID, na ...

  8. 安装个wampserver 环境 执行php

    php代码执行要有相关环境. 在这里推荐一个环境工具.wampserver :内置了下面工具: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5 ...

  9. UML类图中的几种关系总结

           UML类图,描写叙述对象和类之间相互关系的方式包含:依赖(Dependency).关联(Association).聚合(Aggregation).组合(Composition).泛化(G ...

  10. OpenCASCADE中散乱Edge生成Wire

    OpenCASCADE中散乱Edge生成Wire eryar@163.com Abstract. In OpenCASCADE a wire can be built from any number ...