Android MVP开发模式解析
程序员文章站
2022-05-12 15:27:03
...
MVP(Model-View-Presenter),Model提供数据,View界面显示,Presenter业务逻辑处理
MVP从经典的模式MVC演变而来,其主要优点是变成面向接口开发。即把UI视图逻辑提取到View接口处理,把业务逻辑提取到Presenter接口中处理,而View不能直接对Model进行操作,所有的交互都发生在Presenter内部,让Presenter从Model中获取数据后再处理最终返回给View显示,当然Presenter与Mode和View的沟通也都是通过接口进行的,目的是简化Activity中代码、职责单一、提高阅读性、降低耦合。
MVP和MVC的区别
MVP模型
Model: 实体模型,数据源
View: 对应于Activity,负责UI的绘制和用户的交互
Presenter: View和Mode沟通的桥梁以及业务逻辑处理
特点
View不能直接对Model进行操作,必须通过Presenter进行中转
MVC模型
Model:实体模型,数据源
View:布局文件
Controllor:对应于Activity
特点
View可以与Model直接交互
MVP优缺点
MVP的优点
- 降低耦合度
- 模块职责划分明显
- 结构清晰,代码灵活,维护方便
- 提高阅读性
- 方便测试
缺点
- 类比较多
使用示例-获取验证码
创建一个总体协调器,包括Model、View、Presenter各接口
public interface CodeContract {
interface CodePresenter extends BasePresenter {
/**
* 提交验证码信息
*/
void submitCodeInfo(String phone);
}
interface CodeView extends BaseView {
/**
* 获取验证码成功
*/
void obtainCodeSuccess(String response);
/**
* 获取验证码失败
*/
void obtainCodeFailure(String msg);
}
interface CodeModel {
/**
* 获取验证码网络数据
*/
void getCodeInfo(String phone, OnListener onListener);
}
}
Base类
/**
* Created by yunzhao.liu on 2017/12/22
*/
public interface BasePresenter {
/**
* Activity销毁时,销毁各对象
* 避免Activity内存泄漏
*/
void onDestroy();
}
/**
* Created by yunzhao.liu on 2017/12/22
*/
public interface BaseView {
/**
* 获取当前控件的Context
*/
Context getContext();
/**
* 网络是否可用
*/
boolean isNetConnect();
/**
* 显示加载框
*/
void showLoading();
/**
* 隐藏加载框
*/
void hideLoading();
}
网络请求成功、失败接口
public interface OnListener {
/**
* 请求网络成功
* @param response 请求的数据
*/
void onSuccess(String response);
/**
* 请求网络失败
* @param msg 失败提示
*/
void onFailure(String msg);
}
ObtainCodePresenter 负责View和Model的交互
/**
* Created by yunzhao.liu on 2017/12/22
* 负责View和Model的交互
*/
public class ObtainCodePresenter implements CodeContract.CodePresenter {
private CodeContract.CodeView mView;
private CodeContract.CodeModel mModel;
public ObtainCodePresenter(CodeContract.CodeView view) {
this.mView = view;
mModel = new ObtainCodeModel();
}
@Override
public void submitCodeInfo(String phone) {
if (mView == null) return;
mView.showLoading();
mModel.getCodeInfo(phone, new OnListener() {
@Override
public void onSuccess(String response) {
if (mView == null) return;
mView.hideLoading();
mView.obtainCodeSuccess(response);
}
@Override
public void onFailure(String msg) {
if (mView == null) return;
mView.hideLoading();
mView.obtainCodeFailure(msg);
}
});
}
@Override
public void onDestroy() {
mView = null;
}
}
ObtainCodeModel 数据源 提供数据
/**
* Created by yunzhao.liu on 2017/12/22
* 数据源 提供数据
*/
public class ObtainCodeModel implements CodeContract.CodeModel {
@Override
public void getCodeInfo(String phone, final OnListener onListener) {
//这里就在UI线程执行
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Random random = new Random();
int code = random.nextInt(10000);
if (true) {
onListener.onSuccess(code + "");
} else {
onListener.onFailure("失败");
}
}
}, 5000);
}
}
Activity调用
public class MainActivity extends AppCompatActivity implements CodeContract.CodeView{
private Button mBtn1;
private CodeContract.CodePresenter mCodePresenter;
private ProgressBar mPb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initClick();
initPresenter();
}
private void initView() {
mBtn1 = findViewById(R.id.btn1);
mPb = findViewById(R.id.pb);
}
private void initClick() {
mBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
click1Btn();
}
});
}
private void click1Btn() {
mCodePresenter.submitCodeInfo("111222333444");
}
private void initPresenter() {
mCodePresenter = new ObtainCodePresenter(this);
}
@Override
public void obtainCodeSuccess(String response) {
mPb.setVisibility(View.GONE);
Toast.makeText(this, response, Toast.LENGTH_SHORT).show();
}
@Override
public void obtainCodeFailure(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
@Override
public Context getContext() {
return this;
}
@Override
public boolean isNetConnect() {
return false;
}
@Override
public void showLoading() {
mPb.setVisibility(View.VISIBLE);
}
@Override
public void hideLoading() {
mPb.setVisibility(View.GONE);
}
@Override
protected void onDestroy() {
mCodePresenter.onDestroy();
super.onDestroy();
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cn.lyz.demom.MainActivity">
<Button
android:id="@+id/btn1"
android:text="获取验证码"
android:layout_width="match_parent"
android:layout_centerVertical="true"
android:layout_height="80dp"/>
<ProgressBar
android:id="@+id/pb"
style="?android:attr/progressBarStyleInverse"
android:layout_width="80dp"
android:layout_centerInParent="true"
android:layout_above="@+id/btn1"
android:visibility="gone"
android:layout_height="80dp" />
</RelativeLayout>
上一篇: AI怎么绘制一款镂空立体感LOGO?
下一篇: C语言学习笔记