服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - 详解Android MVP开发模式

详解Android MVP开发模式

2021-05-12 16:32Sky、清 Android

这篇文章主要为大家介绍了Android MVP开发模式的相关资料,需要的朋友可以参考下

本文主要讲解mvp开发模式以及具体实例。

一、简介

mvp(model view presenter)模式是著名的mvc(model view controller)模式的一个演化版本,目前它在android应用开发中越来越重要了。初看起来我们会感觉增加了很多类接口代码看起来更加清晰。

mvp模式可以分离显示层和逻辑层,所以功能接口如何工作与功能的展示可以实现分离,mvp模式理想化地可以实现同一份逻辑代码搭配不同的显示界面。不过mvp不是一个结构化的模式,它只是负责显示层而已,任何时候都可以在自己的项目结构中使用mvp模式。(不局限于android项目开发)

因为mvp其实就是从mvc模式演化产生的,那么我们先看一下著名的mvc模式:

  •       view:对应于布局文件
  •       model:业务逻辑和实体模型
  •      controller:控制器,android中对应于activity

对应的交互图如下:

详解Android MVP开发模式

虽然android系统应用开发本身是遵循mvc开发模式的,但是我们仔细看一下view层和activity,具体view布局文件中的数据绑定和事件处理的方法代码都是冗余在activity中的,所以我们经常看可以看到activity类动不动就是少则九百行,多则上千甚至几千行。那么现在的演化升级版本的mvp的模式又是怎么样的呢?mvp模式会引入  presenter层,该机型复杂完成view层和model层的交互,那么具体mvp对应如下:

  •       view:view通常来说是由activity实现的,它会包含一个presenter的引用,view要做的就只是在每次有接口调用的时候(比如按钮点击后)调用presenter的方法。
  •        model:业务逻辑和实体模型
  •       presenter:主要作为沟通view和model的桥梁,它从model层检索数据后,返回给view层,但是不像mvc结构,因为它也可以决定与view层的交互操作。

数据交互图如下:

详解Android MVP开发模式

观察上面两个模式的交互图,是不是mvp模式更加清晰简单啊!

二、mvc和mvp区别

我们来具体看一下下面两张对比,就可以看来具体区别了:

详解Android MVP开发模式

观察上图我们可以发现mvp模式中,view 和model的交互是通过presenter来进行完成,这样统一管理,逻辑会更加清晰。

三、mvp模式例子讲解

3.1.具体实现功能需求:我们是用mvp模式来进行实现用户登录操作.

3.2.例子实例如下:

详解Android MVP开发模式

3.3.项目代码框架如下:

详解Android MVP开发模式

3.4.代码具体实现:

3.4.1.model层:bean类(entity),personbean类,然后在业务逻辑类中有登录方法,同时把登录成功状态回调接口传入进入,具体如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.chinaztt.fda.entity;
/**
* 当前类注释:用户信息实体类
* 项目名:fastdev4android
* 包名:com.chinaztt.fda.entity
*/
public class personbean {
private string username;
private string password;
public personbean() {
}
 
public personbean(string username, string password) {
this.username = username;
this.password = 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;
}
 
@override
public string tostring() {
return "personbean{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
 
'}';
}
}
?
1
2
public interface ipersonbiz {
void login(string username,string password,loginrequestcallback valuecallback);
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.chinaztt.fda.biz.imp;
import com.chinaztt.fda.biz.ipersonbiz;
import com.chinaztt.fda.biz.loginrequestcallback;
import com.chinaztt.fda.entity.personbean;
import com.chinaztt.fda.utils.log;
/**
* 当前类注释:用户相关业务逻辑实现类
* 项目名:fastdev4android
* 包名:com.chinaztt.fda.biz.imp
*/
public class personbizimp implements ipersonbiz{
private static final string tag="personbizimp";
@override
public void login(final string username, final string password, final loginrequestcallback valuecallback) {
log.d(tag,"username:"+username+",password:"+password);
new thread(new runnable() {
@override
public void run() {
try {
thread.sleep(4500);
} catch (interruptedexception e) {
e.printstacktrace();
}
//进行开始登录,这边应该进行请求服务器,进行数据验证
if(username.equals("jiangqq")&&password.equals("12345")){
valuecallback.loginsuccess(new personbean(username,password));
}else{
valuecallback.loginfailed();
}
}
}).start();
}
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.chinaztt.fda.biz;
import com.chinaztt.fda.entity.personbean;
/**
* 当前类注释:登录请求结果回调
* 项目名:fastdev4android
* 包名:com.chinaztt.fda.biz
*/
public interface loginrequestcallback {
//登录成功回调方法
void loginsuccess(personbean personbean);
//登录失败回调方法
void loginfailed();
}

3.4.2.view层:该通过presenter与view进行交互,这边需要定义一个接口iloginview:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.chinaztt.fda.ui.view;
import com.chinaztt.fda.entity.personbean;
/**
* 当前类注释:登录页面 相关操作 功能接口
* 项目名:fastdev4android
* 包名:com.chinaztt.fda.ui.view
*/
public interface iloginview {
//获取用户名
string getusername();
//获取密码
string getpassword();
 
void showsuccessinfo(personbean personbean);
void showfailedinfo();
}

有了上面的接口之后,我们就需要写我们的实现类activity了,就非常简单了

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.chinaztt.fda.test;
import android.os.bundle;
import android.view.view;
import android.widget.button;
import android.widget.edittext;
import com.chinaztt.fda.entity.personbean;
import com.chinaztt.fda.presenter.loginpresenter;
import com.chinaztt.fda.ui.r;
import com.chinaztt.fda.ui.base.baseactivity;
import com.chinaztt.fda.ui.view.iloginview;
import com.chinaztt.fda.utils.log;
import org.androidannotations.annotations.eactivity;
/**
* 当前类注释:mvp开发模式实例
* 项目名:fastdev4android
* 包名:com.chinaztt.fda.test
*/
@eactivity
public class mvptestactivity extends baseactivity implements iloginview{
private static final string tag="mvptestactivity";
private edittext ed_username;
private edittext ed_password;
private button btn_login;
private loginpresenter mloginpresenter;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.mvp_test_layout);
ed_username=(edittext)this.findviewbyid(r.id.ed_username);
ed_password=(edittext)this.findviewbyid(r.id.ed_password);
btn_login=(button)this.findviewbyid(r.id.btn_login);
mloginpresenter=new loginpresenter(this);
btn_login.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
mloginpresenter.loginsystem();
}
});
}
/**
* 进行返回用户名信息
* @return
*/
@override
public string getusername() {
return ed_username.gettext().tostring().trim();
}
/**
* 进行返回用户密码信息
* @return
*/
@override
public string getpassword() {
return ed_password.gettext().tostring().trim();
}
/**
* 登录成功 回调
* @param personbean
*/
@override
public void showsuccessinfo(personbean personbean) {
log.d(tag,"showsuccessinfo:"+personbean.tostring());
showtoastmsgshort("登录成功:"+personbean.tostring());
}
/**
* 登录失败 回调
*/
@override
public void showfailedinfo() {
log.d(tag,"showfailedinfo...");
showtoastmsgshort("登录失败...");
}
}

最后还少一个交互桥梁presenter:
3.4.3.presenter层:作为model和view之间的交互桥梁,在本例中进行执行登录操作,然后去model业务中执行登录,最后把登录结果信息返回给view层,就是这么简单:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.chinaztt.fda.presenter;
import android.os.handler;
import com.chinaztt.fda.biz.ipersonbiz;
import com.chinaztt.fda.biz.loginrequestcallback;
import com.chinaztt.fda.biz.imp.personbizimp;
import com.chinaztt.fda.entity.personbean;
import com.chinaztt.fda.ui.view.iloginview;
import com.chinaztt.fda.utils.log;
/**
* 当前类注释:负责完成登录界面view于model(ipersonbiz)间的交互
* 项目名:fastdev4android
* 包名:com.chinaztt.fda.presenter
*/
public class loginpresenter {
private static final string tag="loginpresenter";
private iloginview mloginview;
private ipersonbiz mpersonbiz;
private handler mhandler=new handler();
public loginpresenter(iloginview view) {
mloginview = view;
mpersonbiz = new personbizimp();
}
public void loginsystem(){
mpersonbiz.login(mloginview.getusername(), mloginview.getpassword(), new loginrequestcallback() {
/**
* 登录成功
* @param personbean
*/
@override
public void loginsuccess(final personbean personbean) {
log.d(tag, "登录成功:" + personbean.tostring());
mhandler.post(new runnable() {
@override
public void run() {
mloginview.showsuccessinfo(personbean);
}
});
}
/**
* 登录失败
*/
@override
public void loginfailed() {
log.d(tag,"登录失败...");
mhandler.post(new runnable() {
@override
public void run() {
mloginview.showfailedinfo();;
}
});
}
});
}
}

到此我们的mvp模式的例子就大体完成了,看一下上面的效果演示就ok了。

以上就是本文的全部内容,希望对大家学习android软件编程有所帮助。

延伸 · 阅读

精彩推荐