定义
全名是Model View Presenter,是模型(model)-视图(view)-主持人(Presenter)的缩写。是在MVC基础上改进的。
效果图
请求前* 请求后
两种模式的主要区别:
- View与Model并不直接交互,而是通过与Presenter交互来与Model间接交互。而在MVC中View可以与Model直接交互
- 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。而Controller是基于行为的,并且可以被多个View共享,Controller可以负责决定显示哪个View
- Presenter与View的交互是通过接口来进行的,更有利于添加单元测试。
Android中使用MVP
- 模型层(Model)
- 视图层(View)
- 控制层(Presenter)
详细使用
模型层(Model)
业务模型,建立的数据结构和相关的类,就可以理解为Android的Model,Model是与View无关,而与业务逻辑相关。Model:负责存储、检索、操纵数据(通过接口来降低耦合)。
1.先写一个接口
public interface MvpModel {
interface ModelListener {
void onSuccess(String result);
void onError();
}
void getData(String url, ModelListener modelListener);
}
2.继承接口进行数据请求
public class MvpModelImpl implements MvpModel {
@Override
public void getData(String url, final ModelListener modelListener) {
OkHttpClient okHttpClient = new OkHttpClient();
// RequestBody requestBody =new FormEncodingBuilder().add().build();
Request request = new Request.Builder().url(url).get().build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
if (response.isSuccessful()) {
String json = response.body().string();
if (modelListener != null) {
modelListener.onSuccess(json);
} else {
modelListener.onError();
}
}
}
});
}
}
视图层(View)
使用XML文件进行绘制应用界面,这些XML可以理解为Android的View。而且便于后期界面的修改。如果逻辑与界面对应的id不变化,则代码不用修改,大大增强了代码的可维护性,还有与用户进行交互(在Android中体现为Activity)。
1.写一个界面应该发生的情况(主要体现在交互上)
public interface MvpView {
/**
* 为了用户体验
*/
//加载中
void showProgress();
//加载中隐藏
void hideProgress();
//加载数据失败
void setError();
//加载数据成功
void setSuccess(Bitmap bitmap);
}
2.看看Activity(现在主要体现在View上)
public class MvpActivity extends Activity implements MvpView {
MvpPresenter mvpPresenter;
String url = "http://image.baidu.com/channel/listjson?pn=1&rn=1&tag1=美女&tag2=全部&ie=utf8";
private Button button;
private ImageView imageView;
private ProgressBar progressBar;
private Bitmap bitmap;
Message message1,message2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mvp_activity);
initView();
initData();
}
public void initView() {
button = findView(R.id.button);
imageView = findView(R.id.imageView);
progressBar = findView(R.id.progressbar);
}
public void initData() {
mvpPresenter = new MvpPresenterImpl(this);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mvpPresenter.getData(url);
}
});
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
imageView.setImageBitmap(bitmap);
break;
case 2:
progressBar.setVisibility(View.GONE);
break;
}
}
};
@Override
public void showProgress() {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void hideProgress() {
message2 = handler.obtainMessage();
message2.what = 2;
handler.sendMessage(message2);
}
@Override
public void setError() {
button.setText("Error");
}
@Override
public void setSuccess(Bitmap bitmap) {
this.bitmap = bitmap;
message1 = handler.obtainMessage();
message1.what = 1;
handler.sendMessage(message1);
}
protected <T extends View> T findView(int id) {
//return返回view时,加上泛型T
return (T) findViewById(id);
}
主持人(Presenter)
作为View与Model交互的中间枢纽,负责逻辑的处理,处理与用户交互。
1.写一个Presenter接口,实现需要的逻辑,联系Model
public interface MvpPresenter {
void getData(String url);
}
2.继承上面创建的逻辑,和model的回调
public class MvpPresenterImpl implements MvpPresenter, MvpModel.ModelListener {
MvpView mvpView;
MvpModel mvpModel;
Gson gson;
private Bitmap bitm;
private String imageUrl;
public MvpPresenterImpl(MvpView mvpView) {
//构造方法,从这里看到Presenter链接了View和Model
this.mvpView = mvpView;
this.mvpModel = new MvpModelImpl();
gson = new Gson();
}
@Override
public void onSuccess(String result) {
//解析数据
PictureBean pictureBean = gson.fromJson(result, PictureBean.class);
List<PictureBean.DataBean> list = pictureBean.getData();
if (list != null) {
imageUrl = list.get(0).getImage_url();
bitm = getHttpBitmap(imageUrl);
}
if (mvpView != null) {
mvpView.setSuccess(bitm);
mvpView.hideProgress();
}
}
@Override
public void onError() {
if (mvpView != null) {
mvpView.setError();
mvpView.hideProgress();
}
}
@Override
public void getData(String url) {
if (mvpView != null) {
mvpView.showProgress();
}
mvpModel.getData(url, this);
}
/**
* 获取网落图片资源
*
* @param url
* @return
*/
public static Bitmap getHttpBitmap(String url) {
URL myFileURL;
Bitmap bitmap = null;
try {
myFileURL = new URL(url);
//获得连接
HttpURLConnection conn = (HttpURLConnection) myFileURL.openConnection();
//设置超时时间为6000毫秒,conn.setConnectionTiem(0);表示没有时间限制
conn.setConnectTimeout(6000);
//连接设置获得数据流
conn.setDoInput(true);
//不使用缓存
conn.setUseCaches(false);
//这句可有可无,没有影响
//conn.connect();
//得到数据流
InputStream is = conn.getInputStream();
//解析得到图片
bitmap = BitmapFactory.decodeStream(is);
//关闭数据流
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
源码下载地址(看源码的MVP文件):点击下载