31.Android MVP模式
Android MVP介绍
先说说MVC吧,MVC(Model-View-Controller)是Java中一种非常常用的开发模式。但是在Android中,View的话可以很容易想到Activity和Fragment,但是Controller的话,我们怎么想都还是Activity,因为无论是Activity还是Fragment跳转的话,都要执行startActivity
,所以无论怎么想,Controller都是由Activity在兼职。。
Activity身兼View和Controller的职位,导致代码过度耦合,上千行也是常有的。
MVP(Model-View-Presenter)MVP的主要思想:
Activity或Fragment的UI逻辑对象抽象成View Interface,业务逻辑抽象成Presenter Interface,M不变。
Activity上只做简单回调接口的数据渲染,组件的简单操作。剩下的耗时工作(网络请求)都交给Presenter去执行。Presenter是Model和View的桥梁,Presenter处理网络请求后拿到的数据实例化Model,然后再将Model通过View Interface回调给View。
MVC 和 MVP 的区别: MVP中的View不能对Model直接操作。
Android MVP UML图
Android MVP实现
实体类 - Topic
public class Topic {
/**
* 用户Id
*/
public Long userId;
/**
* 主题Id
*/
public Long topicId;
/**
* 主题内容
*/
public String content;
}
Presenter层回调View层接口 - IMvpView
public interface IMvpView {
/**
* 添加成功
* @param topic
*/
void addSuccess(Topic topic);
/**
* 删除成功
* @param topic
*/
void delSuccess(Topic topic);
/**
* 修改成功
* @param newTopic
*/
void modSuccess(Topic newTopic);
/**
* 查询成功
* @return
*/
void querySuccess(List<Topic> topics);
/**
* 发生错误
*/
void error();
}
Model层 接口 - ITopicModel
public interface ITopicModel {
/**
* 添加Topic
*
* @param topic
*/
void add(Topic topic);
/**
* 删除主题
*
* @param topic
*/
void del(Topic topic);
/**
* 修改主题
*
* @param topicId
* @param topic
*/
void mod(Long topicId, Topic topic);
/**
* 查询主题
*
* @return
*/
void query();
}
Model层回调Presenter层抽象类 - TopicModelCallBack
public abstract class TopicModelCallBack {
/**
* 添加成功
*
* @param topic
*/
public void addSuccess(Topic topic) {
}
/**
* 删除成功
*
* @param topic
*/
public void delSuccess(Topic topic) {
}
/**
* 修改成功
*
* @param newTopic
*/
public void modSuccess(Topic newTopic) {
}
/**
* 查询成功
*
* @return
*/
public void querySuccess(List<Topic> topics) {
}
/**
* 发生错误
*/
public abstract void error();
}
Model 实现类 - TopicModel
public class TopicModel implements ITopicModel {
private TopicModelCallBack callBack;
public TopicModel(TopicModelCallBack callBack) {
this.callBack = callBack;
}
/**
* 添加Topic
*
* @param topic
*/
@Override
public void add(Topic topic) {
// TODO ...网络请求后...
// TODO 返回数据 这里默认为返回原数据
this.callBack.addSuccess(topic);
}
/**
* 删除主题
*
* @param topic
*/
@Override
public void del(Topic topic) {
// TODO ...网络请求后...
// TODO 返回数据 这里默认为返回原数据
this.callBack.delSuccess(topic);
}
/**
* 修改主题
*
* @param topicId
* @param topic
*/
@Override
public void mod(Long topicId, Topic topic) {
// TODO ...网络请求后...
// TODO 返回数据 这里默认为返回原数据
this.callBack.modSuccess(topic);
}
/**
* 查询主题
*
* @return
*/
@Override
public void query() {
// TODO ...网络请求后...
// TODO 返回数据
Topic topic = new Topic();
topic.userId = 267L;
topic.topicId = 1267L;
topic.content = "Save you from anything";
List<Topic> list = new LinkedList<Topic>();
list.add(topic);
this.callBack.querySuccess(list);
}
}
Presenter层 - MvpPresenter
public class MvpPresenter {
private IMvpView iView;
private ITopicModel model;
public MvpPresenter(IMvpView iView) {
this.iView = iView;
this.model = new TopicModel(new TopicModelCallBack() {
/**
* 添加成功
*
* @param topic
*/
@Override
public void addSuccess(Topic topic) {
MvpPresenter.this.iView.addSuccess(topic);
}
/**
* 删除成功
*
* @param topic
*/
@Override
public void delSuccess(Topic topic) {
MvpPresenter.this.iView.delSuccess(topic);
}
/**
* 修改成功
*
* @param newTopic
*/
@Override
public void modSuccess(Topic newTopic) {
MvpPresenter.this.iView.modSuccess(newTopic);
}
/**
* 查询成功
*
* @param topics
* @return
*/
@Override
public void querySuccess(List<Topic> topics) {
MvpPresenter.this.iView.querySuccess(topics);
}
/**
* 发生错误
*/
@Override
public void error() {
MvpPresenter.this.iView.error();
}
});
}
/**
* 添加主题
*
* @param topic
*/
public void addTopic(Topic topic) {
this.model.add(topic);
}
/**
* 删除主题
*
* @param topic
*/
public void delTopic(Topic topic) {
this.model.del(topic);
}
/**
* 修改主题
*
* @param topic
*/
public void modTopic(Topic topic) {
this.model.mod(topic.topicId, topic);
}
/**
* 查询主题
*/
public void queryTopic() {
this.model.query();
}
}
Activity
public class MvpActivity extends AppCompatActivity implements IMvpView {
private TextView addTV;
private TextView delTV;
private TextView modTV;
private TextView queryTV;
private MvpPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
this.addTV = (TextView) this.findViewById(R.id.add_tv);
this.delTV = (TextView) this.findViewById(R.id.del_tv);
this.modTV = (TextView) this.findViewById(R.id.mod_tv);
this.queryTV = (TextView) this.findViewById(R.id.query_tv);
this.presenter = new MvpPresenter(this);
Topic topic = new Topic();
topic.userId = 267L;
topic.topicId = 1267L;
topic.content = "Save you from anything";
this.presenter.addTopic(topic);
this.presenter.delTopic(topic);
this.presenter.modTopic(topic);
this.presenter.queryTopic();
}
/**
* 添加成功
*
* @param topic
*/
@Override
public void addSuccess(Topic topic) {
Log.i("MvpActivity", topic.content);
this.addTV.setText("Add:"+topic.content);
}
/**
* 删除成功
*
* @param topic
*/
@Override
public void delSuccess(Topic topic) {
Log.i("MvpActivity",topic.content);
this.delTV.setText("Del:"+topic.content);
}
/**
* 修改成功
*
* @param newTopic
*/
@Override
public void modSuccess(Topic newTopic) {
Log.i("MvpActivity", newTopic.content);
this.modTV.setText("Mod:" + newTopic.content);
}
/**
* 发生错误
*/
@Override
public void error() {
}
/**
* 查询成功
*
* @param list
* @return
*/
@Override
public void querySuccess(List<Topic> list) {
Topic topic = list.get(0);
Log.i("MvpActivity",topic.content);
this.queryTV.setText("Query:"+topic.content);
}
}
Android MVP项目结构
Android MVP作用
在Android上,分离了View和Controller,大大降低了耦合度。
Activity只处理简单的事情,代码干净。
Presenter被抽象出来可以有多种具体的实现,方便进行单元测试。
Presenter和View都独立出来了,不互相耦合,提升了各自功能的特点和可读性(比如Presenter就是干这个的,View是干这个的,很容易看出来)。
网络的耗时任务内,可能Activity的引用还被耗时任务引用着,这样会造成内存泄露,如果业务逻辑交给Presenter,可以在onDestory的时候让Presenter分离耗时任务和Activity的引用。