Android MVP 简析
来源:互联网 发布:汇率软件 编辑:程序博客网 时间:2024/05/22 03:08
最近在研究MVP的使用,看了几篇介绍的,综合了Google的MVPdemo介绍。简单的说一下。
https://github.com/zhuyongit/MVPDemo 这篇说的感觉还不错,分析的挺透彻。
http://www.jianshu.com/p/14283d8d3a60 这个是Google的MVP简单的介绍。
然后综合了一下。写了一个感觉比较适合自己的。
一:基本概念
不管是MVC还是MVP , 都是为了将数据,处理逻辑,与界面分离 , 以达到低耦合的效果 。MVP模式,主要是面向接口编程 , 将Model与View都抽象成一个接口,用一个Presenter来关联View与Model,Presenter做到一个绑定数据控制界面的中间者 。
MVC:M(Model)V(View)C(Controller)
MVP:M(Model)V(View)P(Presenter)
其实画下UML图对框架的理解真是蛮大的。
P层持有M层和V层的对象,将M与V关联起来 , 在MVP中将Model与View的操作接口化 , 通过接口回调来完成数据的传递 。
传统的MVP不能更直观的看到IView中的方法和Presenter中的方法的关联。我这里多了一个contract包:里面放的是契约接口。更能直接明了的看到View和Presenter之间的方法。具体的模型图:
① 编写IModel接口 , 定义获取数据的方法以及显示时需要的数据对象 , 这里是一个列表,所以是一个List集合。具体实现 , 则需要创建一个Class来实现IModel接口。
/** * Created by pepys on 2016/11/10. * 编写IModel接口 , 定义获取数据的方法以及显示时需要的数据对象 ,定义一个类来实现IModel接口。 */public interface ICommissionModel { /*加载数据*/ void loadDatas(HashMap<String,String> params,CommissionLoadListener listener); /*数据加载完将数据回调给调用者*/ interface CommissionLoadListener { void onComplate(ArrayList<CommissionBean> commissionList); void onError(); }}
② 编写实现类 , 首先编写IModel的实现类 。IModel的实现类 , 其主要功能就是获取网络数据 , 并将数据处理成对象,返回给BookLoadListener监听接口。
** * Created by pepys on 2016/11/10. * 编写IModel的实现类 。IModel的实现类 , 其主要功能就是获取网络数据 , 并将数据处理成对象,返回给listener监听接口。 */public class CommissionModelImpl implements ICommissionModel { @Override public void loadDatas(HashMap<String, String> params, final CommissionLoadListener listener) { OkHttpHelper.getInstance().postHttps(ApiCommission.MOD_NAME, ApiCommission.Commission_Datail, null, params, new OkHttpCallBack() { @Override public Object parseData(String data, int status, String serviceMessage) { if (data.equals("") && status == 0) { if (!serviceMessage.equals("")) { ToastUtils.showToast(serviceMessage); } return null; } else { ArrayList<CommissionBean> commissionList; if (data.equals("null")) { commissionList = new ArrayList<>(); } else { commissionList = new Gson().fromJson(data, new TypeToken<ArrayList<CommissionBean>>() { }.getType()); } return commissionList; } } @Override public void onError(Call call, Exception e, int id) { e.printStackTrace(); ToastUtils.showToast(R.string.net_work_error); listener.onError(); } @Override public void onResponse(Object response, int id) { if (response == null) { listener.onError(); } else { listener.onComplate((ArrayList<CommissionBean>) response); } } });}
③ 编写Contract契约接口,定义ViewInterface显示的方法,首先定义一个加载数据进度的方法,还可以加一个加载完成的方法来显示View,接着定义一个显示列表的方法。定义Presneter。
/** * Created by pepys on 2016/11/22. * 佣金明细契约接口 */public interface CommissionContract { interface ViewInterface { /*加载loading*/ void showLoading(); /*隐藏loading*/ void hideLoading(); /*显示数据*/ void showCommissionList(ArrayList<CommissionBean> commissionList); /*加载失败*/ void LoadFailure(); } interface Presneter extends BasePresenter{ /** * 加载数据 * @param page * @param count */ void loadCommission(String page, String count); }}
④ 编写Presenter , 定一个两个接口的引用,Model在创建类的时候就创建 , 而View则是通过创建Presenter对象进行传递 。在Presenter里面 , 写一个fetch()将Model与View关联起来 。
/** * Created by pepys on 2016/11/10. * 定一个两个接口的引用,Model在创建类的时候就创建 , 而View则是通过创建Presenter对象进行传递 。在Presenter里面 , 写一个fetch()将Model与View关联起来 。 */public class CommissionPresneter implements CommissionContract.Presneter { /*持有View Model*/ // View CommissionContract.ViewInterface mCommissionView; // model ICommissionModel mCommissionModel = new CommissionModelImpl(); /*通过构造方法实现View*/ public CommissionPresneter(CommissionContract.ViewInterface mCommissionView) { this.mCommissionView = mCommissionView; } /** * @param page 页数 * @param count 每页数量 */ @Override public void loadCommission(String page, String count) { if (mCommissionView != null) { HashMap<String, String> params = new HashMap<>(); params.put("page", page); params.put("count", count); mCommissionView.showLoading(); mCommissionModel.loadDatas(params, new ICommissionModel.CommissionLoadListener() { @Override public void onComplate(ArrayList<CommissionBean> commissionList) { mCommissionView.hideLoading(); mCommissionView.showCommissionList(commissionList); } @Override public void onError() { mCommissionView.hideLoading(); mCommissionView.LoadFailure(); } }); } } @Override public void start() { }}
⑤ 编写IView的实现 , Activity实现IView接口 , 进行View的显示与控制。
public class CommissionActivity extends BaseActivity<CommissionPresneter> implements CommissionContract.ViewInterface { @Override protected int setLayoutId() { return R.layout.activity_commission; } @Override protected CommissionPresneter createPresenter() { return new CommissionPresneter(this); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPresneter.loadCommission(page, count); } @Override public void showLoading() { } @Override public void hideLoading() { } @Override public void showCommissionList(ArrayList<CommissionBean> commissionList) { } @Override public void LoadFailure() { }}
写了一个baseActivity。创建Presenter()
/** * Created by pepys on 2016/11/10. */public abstract class BaseActivity<T extends BasePresenter> extends ThinksnsAbscractActivity { protected T mPresneter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreateNoTitle(savedInstanceState); /*创建Presenter*/ mPresneter = createPresenter(); } /** * create presenter * * @return */ protected abstract T createPresenter();}
BasePresenter 想的里面写一些通用方法。
public interface BasePresenter { void start();}
由上述可以看出 , MVP,将M与V分隔开来 , 使得代码与逻辑都比较清晰 , 不会出现你引用了我 , 我又引用了你 , 最后不知道谁引用了谁 , 导致对象占据内存,或出现对象空指针等问题 。
MVP现在在Android中应用越来越广泛了 。虽然项目文件会比较多 , 但是结构清晰 , 不仅小型项目可以直接使用MVP作为项目架构 , 大型项目也可以在模块或组件中使用MVP模式 。
2017-03-20:
最近有时间写了一个简单的MVPDemo。欢迎大家指教:https://github.com/PepysZhu/MVPDemo
- Android MVP 简析
- android MVP
- android mvp
- android MVP
- Android MVP
- Android MVP
- android MVP
- Android MVP
- Android MVP
- Android mvp
- android MVP
- android mvp
- Android MVP
- Android MVP
- Android MVP
- Android MVP
- Android MVP
- Android MVP
- Collection与Collections
- 【框架-MFC】获取当前鼠标的ICON图标(光标)
- Spring task quartz 定时任务的几种实现
- HDU5882——Balanced Game(2016年青岛区域赛网络赛)
- Fast特征点检测
- Android MVP 简析
- 微分
- js验证时间正则表达式
- hbase伪分布式搭建
- thinkphp ajax 进入error 返回多个红点 解决方法
- 异步同步,阻塞非阻塞
- HTML5调用手机摄像机、相册功能 <input>方法
- 启动eclipse报错 Could not create the Java Virtual Machine 解决办法
- 制作AppCan插件的那些坑