一、首先介绍什么是MVP?
MVP是模型(Model)、视图(View)、主持人(Presenter)的缩写,分别代表三个模块。
模型(Model):负责处理数据的加载或者存储,例如网络或本地数据库数据的获取等等;
视图(View):负责界面数据的展示,与用户进行交流;
二、MVP的模块之间交互
如下图所示:View和Model不会直接去交互,而是通过Presenter作为View和Model的桥梁,其中Presenter中同时持有View层以及Model层的Interface的引用,而View层持有Presenter层的Interface引用。当View层某个界面需要展示某些数据时,首先会调用Presenter层的接口,然后Presenter层会调用Model层进行数据请求操作,当Model层的数据请求完成的时候就会调用Presenter层的回调方法通知Presenter层数据加载完成,最后由Presenter层再调用View层的接口将加载的数据显示在界面上展示给用户。这就是MVP模式的核心过程。
三、MVP的优缺点:
优点:1、View和Model之间的耦合度降低,使其更关注与自身的业务逻辑,结构清晰维护方便。
2、便于单元测试。
3、代码复用度提高。
4、代码框架更适用于快速的迭代开发
缺点:主要为每一个View都有Presenter,类比较多书写起来麻烦
四、MVP在Android开发中的使用:
1、我的MVPdemo的源码目录结构如下:
bean包下为:数据类的定义。
Model,Presenter包下各有两个包,其中的Impl为对其相应包的业务逻辑的操作。
运行效果如下:
源码下载:(http://download.csdn.net/detail/qq_30000411/9687960)
该demo为MVP模式下开发的聊天机器人demo。
2、各个包下的代码如下:
(1)、bean 包下的JiQiRen类为数据类的定义
package com.xyliwp.mvpdemo.bean;
/**
* Created by lwp940118 on 2016/11/20.
*/
public class JiQiRen {
private int tag;
private String message;
public int getTag() {
return tag;
}
public void setTag(int tag) {
this.tag = tag;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
(2)、Model层的两个子包下的文件:
JiQiRenModel为Model层接口的定义
package com.xyliwp.mvpdemo.Model.Model;
import com.xyliwp.mvpdemo.Model.ModelImpl.JiQiRenModelImpl;
/**
* model层的接口
* Created by lwp940118 on 2016/11/20.
*/
public interface JiQiRenModel {
/**
* 加载数据并且的接口
* @param infor
* @param listener
*/
void loadMessage(String infor, JiQiRenModelImpl.OnLoadMessageListListener listener);
}
JiQiRenModelImpl 为Model层的业务逻辑。
package com.xyliwp.mvpdemo.Model.ModelImpl;
import android.os.Handler;
import com.xyliwp.mvpdemo.Model.Model.JiQiRenModel;
import com.xyliwp.mvpdemo.bean.JiQiRen;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Created by lwp940118 on 2016/11/20.
*/
public class JiQiRenModelImpl implements JiQiRenModel{
public static final String api = "http://www.tuling123.com/openapi/api";
public static final String key = "959060c92fb845acb8d9073934355364";
public static final String url = api+"?key="+key+"&info=";
private Handler handler = null;
@Override
public void loadMessage(final String infor, final OnLoadMessageListListener listener) {
handler = new Handler(){
@Override
public void handleMessage(android.os.Message msg) {
JiQiRen message = (JiQiRen) msg.obj;
if (message.getTag() == 1){
listener.onSuccess(message);
}else{
listener.onFailure(message);
}
}
};
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient okHttpClient = new OkHttpClient();
FormBody.Builder builder = new FormBody.Builder();
builder.add("json","true");
RequestBody body = builder.build();
Request request = new Request.Builder()
.url(url+infor)
.post(body)
.build();
try {
Response response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()){
JSONObject jsonObject = new JSONObject(response.body().string());
JiQiRen message = new JiQiRen();
message.setMessage(jsonObject.toString());
message.setTag(1);
android.os.Message message1 = new android.os.Message();
message1.obj = message;
handler.sendMessage(message1);
}else {
JiQiRen message = new JiQiRen();
message.setMessage("小凤异常,小凤异常,小凤异常,重要的事情说三边");
message.setTag(0);
android.os.Message message1 = new android.os.Message();
message1.obj = message;
handler.sendMessage(message1);
}
} catch (IOException e) {
e.printStackTrace();
}catch (JSONException e){
e.printStackTrace();
}
}
}).start();
}
public interface OnLoadMessageListListener{
void onSuccess(JiQiRen message);
void onFailure(JiQiRen message);
}
}
(3)、Presenter层两个子包下的文件
JiQiRenPresenter为Presenter层的接口
这里写代package com.xyliwp.mvpdemo.Presenter.Presenter;
/**
* Created by lwp940118 on 2016/11/20.
*/
public interface JiQiRenPresenter {
/**
* 添加消息的message
* @param message
*/
void loadMessage(String message);
}
JiQiRenPresenterImpl为Presenter层的Model层调用以及View层的数据展示。
package com.xyliwp.mvpdemo.Presenter.PresenterImpl;
import com.xyliwp.mvpdemo.Model.Model.JiQiRenModel;
import com.xyliwp.mvpdemo.Model.ModelImpl.JiQiRenModelImpl;
import com.xyliwp.mvpdemo.Presenter.Presenter.JiQiRenPresenter;
import com.xyliwp.mvpdemo.View.JiQiRenView;
import com.xyliwp.mvpdemo.bean.JiQiRen;
/**
* Created by lwp940118 on 2016/11/20.
*/
public class JiQiRenPresenterImpl implements JiQiRenPresenter,JiQiRenModelImpl.OnLoadMessageListListener{
private JiQiRenView jiQiRenView;
private JiQiRenModel messageModel;
public JiQiRenPresenterImpl(JiQiRenView jiQiRenView){
this.jiQiRenView = jiQiRenView;
this.messageModel = new JiQiRenModelImpl();
}
@Override
public void onSuccess(JiQiRen message) {
jiQiRenView.addMessage(message);
}
@Override
public void loadMessage(String message) {
messageModel.loadMessage(message,this);
}
@Override
public void onFailure(JiQiRen message) {
jiQiRenView.showMessageFailure(message);
}
}
(4)、View层的接口文件
package com.xyliwp.mvpdemo.View;
import com.xyliwp.mvpdemo.bean.JiQiRen;
/**
* 机器人的view
* Created by lwp940118 on 2016/11/20.
*/
public interface JiQiRenView {
/**
* 信息添加成功 展示给接界面
* @param jiQiRen
*/
void addMessage(JiQiRen jiQiRen);
/**
* 添加失败 将失败展示给界面
* @param jiQiRen
*/
void showMessageFailure(JiQiRen jiQiRen);
}
(5)、MVP模式在Android中Activity的调用,向Presenter发送数据请求,和Presenter返回数据显示。
package com.xyliwp.mvpdemo;
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.TextView;
import com.xyliwp.mvpdemo.Presenter.Presenter.JiQiRenPresenter;
import com.xyliwp.mvpdemo.Presenter.PresenterImpl.JiQiRenPresenterImpl;
import com.xyliwp.mvpdemo.View.JiQiRenView;
import com.xyliwp.mvpdemo.bean.JiQiRen;
public class MainActivity extends AppCompatActivity implements JiQiRenView{
private TextView textView;
private EditText editText;
private Button button;
private JiQiRenPresenter messagePresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
messagePresenter = new JiQiRenPresenterImpl(this);
initView();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
messagePresenter.loadMessage(editText.getText().toString());
}
});
}
private void initView(){
textView = (TextView)findViewById(R.id.textview);
editText = (EditText)findViewById(R.id.edittext);
button = (Button)findViewById(R.id.button);
}
@Override
public void addMessage(JiQiRen message) {
String s = message.getMessage();
textView.setText(s);
}
@Override
public void showMessageFailure(JiQiRen message) {
textView.setText(message.getMessage());
}
}
xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="80dp"
android:id="@+id/edittext"/>
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="300dp" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="button"/>
</LinearLayout>
读者可自行结合MVC开发框架来对比理解MVP开发框架