Android -- 初探MVP模式
1,相信大家对mvp模式都很熟悉了,M-Model-模型、V-View-视图、C-Controller-控制器。MVP作为MVC的版本演化,与MVC的意义类似:M-Model-模型、V-View-视图、P-Presenter-表示器。从MVC和MVP两者结合来看,Controlller/Presenter在MVC/MVP中都起着逻辑控制处理的角色,起着控制各业务流程的作用。而 MVP与MVC最不同的一点是M与V是不直接关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层,其负责调控 View与Model之间的间接交互。在 Android中很重要的一点就是对UI的操作基本上需要异步进行也就是在MainThread中才能操作UI,所以对View与Model的切断分离是 合理的。此外Presenter与View、Model的交互使用接口定义交互操作可以进一步达到松耦合也可以通过接口更加方便地进行单元测试。下面是对应的两张图(左图为mvc,右图为mvp):

可以看到最明显的区别是mvc是允许model和view交互的,而mvp中model和view中的交互是由presenter完成的,presenter和view的交互是通过接口来实现的。
2,mvp的实现应用 (例子是大神博客写的,自己只是拿过来来写一下实现的思路,毕竟还是小菜鸟的级别)
先看一下要实现的效果:

再看一下我们工程的目录:

由我们上面的功能需要可以看出,这是一个最常见的登录功能,所以首先我们要创建一个User类,,包含用户名和密码,用于对应用户输入的用户信息
① Model层
User.java
package com.wangjitao.simplelogindemo.bean; /**
* Created by wangjitao on 2016/5/12.
* 用户登录bean
*/
public class User {
private String username ;
private String password ; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
}
}
从上面所给的功能可以看出我们主要是要实现登录功能的,所以至少有一个login()方法
IUserBIZ.java
package com.wangjitao.simplelogindemo.inter; import com.wangjitao.simplelogindemo.listener.OnLoginListener; /**
* Created by wangjitao on 2016/5/12.
*/
public interface IUserBIZ {
public void login(String username ,String password ,OnLoginListener loginListener);
}
它的实现类 UserBIZ.java ,在实现类中我们模拟一个登陆的耗时操作,然后在登录成功的写了一个回调类OnLoginListener.java
UserBIZ.java
package com.wangjitao.simplelogindemo.inter; import com.wangjitao.simplelogindemo.bean.User;
import com.wangjitao.simplelogindemo.listener.OnLoginListener; /**
* Created by jh on 2016/5/12.
*/
public class UserBIZ implements IUserBIZ{ @Override
public void login(final String username, final String password, final OnLoginListener loginListener) {
//开启子线程模拟登录耗时操作
new Thread(){
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//模拟登录成功
if("wjt".equals(username) && "123456".equals(password)){
User user = new User();
user.setUsername(username);
user.setPassword(password);
loginListener.loginSuccess(user);
}else {
loginListener.loginFailed();
}
}
}.start();
}
}
OnLoginListener.java
package com.wangjitao.simplelogindemo.listener; import com.wangjitao.simplelogindemo.bean.User; /**
* Created by wangjitao on 2016/5/12.
*/
public interface OnLoginListener {
void loginSuccess(User user) ;
void loginFailed();
}
②View 层
从我们看到的界面我们可以看到,用户一共有两个按钮,一个是login,那么需要两个方法来获取用户名和密码
String getUserName();
String getPassword();
然后是一个clear按钮,这时候我们要提供两个方法去清空输入框的内容
void clearUserName();
void clearPassword();
然后当用户正在登陆的时候,我们需要一个用户的等待,这时候我们需要加一个进度的提示条
void clearUserName();
void clearPassword();
然后是用户登录后的一些提示,当登陆成功,让用户跳转到下一个界面,当登录失败提示用户用户名或密码错误
void toMainActivity(User user);
void showFailedError();
所以view的接口如下:
package com.wangjitao.simplelogindemo.view; import com.wangjitao.simplelogindemo.bean.User; /**
* Created by jh on 2016/5/12.
*/
public interface IUserLoginView {
String getUserName();
String getPassword(); void showLoading();
void dismissLoading(); void toMainActivity(User user);
void showFailedError(); void clearUserName();
void clearPassword(); }
然后Activity来实现这个接口的方法(Activity也可以当做一个view层)
package com.wangjitao.simplelogindemo; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast; import com.wangjitao.simplelogindemo.bean.User;
import com.wangjitao.simplelogindemo.presenter.UserLoginPresenter;
import com.wangjitao.simplelogindemo.view.IUserLoginView; public class MainActivity extends AppCompatActivity implements IUserLoginView{
private EditText editText_username ,editText_password ;
private Button button_login ,button_clean ;
private ProgressBar progressBar ; private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView();
} private void initView() {
editText_username = (EditText)findViewById(R.id.editText_username);
editText_password = (EditText)findViewById(R.id.editText_password); button_login = (Button)findViewById(R.id.button_login);
button_clean = (Button)findViewById(R.id.button_clean); progressBar = (ProgressBar)findViewById(R.id.progressBar); button_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mUserLoginPresenter.login();
}
}); button_clean.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mUserLoginPresenter.clear();
}
});
} @Override
public String getUserName() {
return editText_username.getText().toString();
} @Override
public String getPassword() {
return editText_password.getText().toString();
} @Override
public void showLoading() {
progressBar.setVisibility(View.VISIBLE);
} @Override
public void dismissLoading() {
progressBar.setVisibility(View.GONE);
} @Override
public void toMainActivity(User user) {
Toast.makeText(MainActivity.this ,"登录成功:欢迎回来"+user.getUsername(),Toast.LENGTH_SHORT).show();
} @Override
public void showFailedError() {
Toast.makeText(MainActivity.this ,"登录失败",Toast.LENGTH_SHORT).show();
} @Override
public void clearUserName() {
editText_username.setText("");
} @Override
public void clearPassword() {
editText_password.setText("");
}
}
③Persenter
这个用与处数据和视图的交互,我们的这个应用主要是login和clear ,所以代码如下:
package com.wangjitao.simplelogindemo.presenter; import android.os.Handler; import com.wangjitao.simplelogindemo.bean.User;
import com.wangjitao.simplelogindemo.inter.IUserBIZ;
import com.wangjitao.simplelogindemo.inter.UserBIZ;
import com.wangjitao.simplelogindemo.listener.OnLoginListener;
import com.wangjitao.simplelogindemo.view.IUserLoginView; /**
* Created by wangjitao on 2016/5/12.
*/
public class UserLoginPresenter {
private IUserBIZ userBIZ ;
private IUserLoginView userLoginView ;
private Handler mHandler = new Handler(); public UserLoginPresenter(IUserLoginView userLoginView){
this.userLoginView = userLoginView ;
userBIZ = new UserBIZ();
} public void login(){
userLoginView.showLoading();
userBIZ.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() {
@Override
public void loginSuccess(final User user) {
mHandler.post(new Runnable() {
@Override
public void run() {
userLoginView.toMainActivity(user);
userLoginView.dismissLoading();
}
});
} @Override
public void loginFailed() {
mHandler.post(new Runnable() {
@Override
public void run() {
userLoginView.showFailedError();
userLoginView.dismissLoading();
}
});
}
});
} public void clear(){
userLoginView.clearUserName();
userLoginView.clearPassword();
}
}
Presenter大致就是从View中获取需要的参数,交给Model去执行业务方法,执行的过程中需要的反馈,以及结果,再让View进行做对应的显示。
这样我们的demo就写完了 ,感觉还是很有成就感的嘛。
Android -- 初探MVP模式的更多相关文章
- Android开发MVP模式解析
http://www.cnblogs.com/bravestarrhu/archive/2012/05/02/2479461.html 在开发Android应用时,相信很多同学遇到和我一样的情况,虽然 ...
- android的MVP模式
MVP简介 相信大家对MVC都是比较熟悉了:M-Model-模型.V-View-视图.C-Controller-控制器,MVP作为MVC的演化版本,那么类似的MVP所对应的意义:M-Model-模型. ...
- 说说Android的MVP模式
http://toughcoder.NET/blog/2015/11/29/understanding-Android-mvp-pattern/ 安卓应用开发是一个看似容易,实则很难的一门苦活儿.上手 ...
- Android开发 MVP模式的规范记录(个人总结)
前言 首先,这篇文章不在讲解什么是mvp模式,如果需要请自行搜索mvp模式文章了解.这个文章里我只记录mvp模式的创建和mvp各自层的界限.另外这个博客属于个人使用mvp模式后一些经验总结与记录.并不 ...
- android中MVP模式(一) - 清风明月的专栏 - CSDN博客
presenter 主持人.主导器 ====== 1. 明确需求,界面如下:可存,可根据id读取数据. 包结构图 2. 建立bean public class UserBean { private S ...
- Android中MVP模式与MVC模式比較(含演示样例)
原文链接 http://sparkyuan.me/ 转载请注明出处 MVP 介绍 MVP模式(Model-View-Presenter)是MVC模式的一个衍生. 主要目的是为了解耦,使项目易于维护. ...
- ym——Android开发MVP模式(攻克了View和Model的耦合)
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! 什么是MVP呢?它又和我们经常听到的MVC有什么关系了以及差别呢? MVP 是从经典的 ...
- Android之MVP模式实现登录和网络数据加载
MVP简介 相信大家对 MVC 都是比较熟悉了:M-Model-模型.V-View-视图.C-Controller-控制器,MVP作为MVC的演化版本,也是作为用户界面(用户层)的实现模式,那么类似的 ...
- (未完成)【Android】MVP模式初见(一)
最近在阅读郭霖大神的公众号时,分类中架构引起了我的注意. 虽然是个人开发(水平很菜的那种),但最终都要向企业正式项目开发靠近.因此接下来一段时间,主要学习一下MVP架构.Retrofit以及RxJav ...
随机推荐
- Python基本数据类型之int 、 float
首先要明确的是:在python中,一切皆为对象. 从底层角度看,对象就是保存在内存中的一个数据块.从抽象层看,对象就是我们的代码模拟出的一个类的独立个体. 在python中变量不需要声明类型,也不需要 ...
- php--求几个数中的最小值
<?phpecho min(2, 3, 1, 6, 7); // 1echo min(array(2, 4, 5)); // 2echo min(0, 'hello'); // 0ec ...
- HTML5音频,视频播放
1.此方法可支持多种浏览器 <audio controls="controls"> <source src="1.mp3" ></ ...
- Express创建并运行node项目(Jade和EJS模版引擎)
1.创建Node项目 [Jade模板] > express nodeJade express创建项目若不显示指定模板,默认使用Jade,以下写法都可以: express -jade nodeJa ...
- Linux中挂载移动硬盘的方法
- fdisk -l 找出移动硬盘对应的设备 - mkdir 创建挂载点 mkdir /mnt/usb - mount mount -t ntfs-3g /dev/sdb1 /mnt/usb - u ...
- spring MVC的困惑--url-pattern的/和/*有区别
总是现象就是:spring用到forward("/WEB-INF/jsp/*.jsp")而forward当然是又要经过web.xml的映射的,然后,在URL匹配时,<url- ...
- Linux中的两种守护进程stand alone和xinetd
Linux中的两种守护进程stand alone和xinetd --http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一 ...
- Android 保持Service不被Kill掉的方法--双Service守护 && Android实现双进程守护
本文分为两个部分,第一部分为双Service守护,第二部分为双进程守护 第一部分: 一.Service简介:Java.lang.Object ↳Android.content.Context ↳an ...
- [BS-10] 统一设置app所有页面的“返回”按钮样式
统一设置app所有页面的“返回”按钮样式 如果想统一设置app所有页面的“返回”按钮样式,首先自定义WZNavigationController类继承UINavigationController类,然 ...
- Spring Boot 5 SpringSecurity身份验证
对于没有访问权限的用户需要转到登录表单页面.要实现访问控制的方法多种多样,可以通过Aop.拦截器实现,也可以通过框架实现(如:Apache Shiro.Spring Security). pom.xm ...