先说说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直接操作。
实体类 - 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上,分离了View和Controller,大大降低了耦合度。
Activity只处理简单的事情,代码干净。
Presenter被抽象出来可以有多种具体的实现,方便进行单元测试。
Presenter和View都独立出来了,不互相耦合,提升了各自功能的特点和可读性(比如Presenter就是干这个的,View是干这个的,很容易看出来)。
网络的耗时任务内,可能Activity的引用还被耗时任务引用着,这样会造成内存泄露,如果业务逻辑交给Presenter,可以在onDestory的时候让Presenter分离耗时任务和Activity的引用。
Mvp4Android Demo