Android MVP设计模式的最佳实现
来源:互联网 发布:arm c语言编程实例 编辑:程序博客网 时间:2024/05/21 09:50
相信大家看这篇文章的时候,应该都是积累了一定的Android实际项目开发经验的,大家一定都是这么经历过来的:所有的业务逻辑实现以及一些界面相关(Dialog,PopWindow....显示)还有网络请求的CallBack都放在Activity里面,从界面的初始化,数据加载,然后根据网络返回显示界面的不同内容,少则一个activity几百行代码,多则上千。我想如果稍微出点bug或者说需求做一些稍微的改动,大家就会烦恼,因为Activity所涉及的业务太多,逻辑太繁杂。可能找一个bug又得从头看一遍代码。下面介绍一下MVP设计模式,从此解耦界面与业务逻辑,轻轻松松对付产品,对付bug.
MVP设计模式简介:
其实说起MVP设计模式,应该要先去了解一下mvc设计模式,android本身就是一种MVC的设计模式:网络,数据库,本地文件的数据存取作为Model,Acitivity作为Controller,而xml文件还有一些界面相关的组件作为View。但是这样的设计在我们真正去做项目的时候可能完美的体现出来么?这是不可能的,往往我们要在Activity里面写很多界面的东西,比如Dialog,PopWindow等等,也就是说,View层和Controller层紧紧联系在一起,造成代码的高度耦合。而且在MVC里,是允许View层直接访问Model层的。而mvp的出现就是用Presenter代替以前的Controller,实现V,C层的完美分离,当然这个实现需要接口的辅助。看完下面的例子就明白了。
MVP完美实现:
1.定义View接口:
public interface ILoginView extends IBaseView { void showNetWorkError(); //显示网络错误 void showLogining();//显示登录中 void showLoginSuccess();//显示登录成功 void showLoginFail(String msg);//显示登录失败,并说明服务器登录错误的原因}IBaseView其实就是一个空的interface,这个具体根据你的项目而定,看看界面需要定义的共同方法是什么,可以加到父接口中,一般用空接口就行了。
2.定义Presenter
public class LoginPresenter extends MvpBasePresenter<ILoginView> { public void login(Context context, String username, String password) { if (isViewAttached()) {//判断界面是否还在(用户没有点返回键) if (Utils.hasNetWork(context)) { //无网络,显示网络无连接 getView().showNetWorkError(); return; } getView().showLogining(); //显示正在登录中 DataModel.login(context, username, password, new NetWorkCallBack() { //访问Model @Override public void onSuccess(String res) { if (isViewAttached()) { getView().showLoginSuccess(); //显示登录成功 } } @Override public void onFail(String failMsg) { if (isViewAttached()) { getView().showLoginFail(failMsg);//显示登录失败 } } }); } }}在看一看MvpBasePresenter(可以作为模板代码直接使用)
public class MvpBasePresenter<V extends MvpView> implements MvpPresenter<V> { private WeakReference<V> viewRef; /** * 界面创建,Presenter与界面取得联系 */ @Override public void attachView(V view) { viewRef = new WeakReference<V>(view); } /** * 获取界面的引用 */ protected V getView() { return viewRef == null ? null : viewRef.get(); } /** * 判断界面是否销毁 */ protected boolean isViewAttached() { return viewRef != null && viewRef.get() != null; } /** * 界面销毁,Presenter与界面断开联系 */ @Override public void detachView(boolean retainInstance) { if (viewRef != null) { viewRef.clear(); viewRef = null; } }}3,最后定义Activity实现View接口
public class LoginActivity extends MvpActivity<ILoginView, LoginPresenter> implements ILoginView { private EditText etUserName, etPassword; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn_login).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { presenter.login(LoginActivity.this, etUserName.getText().toString(), etPassword.getText().toString()); } }); } @Override protected LoginPresenter createPresenter() { return new LoginPresenter(); //具体界面对应的presenter由具体界面决定 } @Override public void showNetWorkError() { Toast.makeText(this, "网络有问题,请检查网路连接", Toast.LENGTH_SHORT).show(); } @Override public void showLogining() { Toast.makeText(this, "正在登录中", Toast.LENGTH_SHORT).show(); } @Override public void showLoginSuccess() { Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show(); } @Override public void showLoginFail(String msg) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); }}看看MvpActivity(可以作为模板代码使用)
public abstract class MvpActivity<V extends MvpView, P extends MvpPresenter> extends Activity implements MvpView { protected P presenter; @SuppressWarnings("unchecked") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); presenter = createPresenter(); presenter.attachView(this); //presenter取得与界面的联系 } @Override protected void onDestroy() { super.onDestroy(); presenter.detachView(false);//presenter断开与界面的联系 } protected abstract P createPresenter();}
好了整个MVP的模板写完了,大家回头看一看,如果这个时候产品跟你说,我这些提示不想要Toast来提示,你改成对话框的形式,那简单啊,直接改Activity那些show方法的实现就可以了,根本不需要再查看一遍逻辑,V C分离就是好,改起来超快。
仅仅只有这一个优点么?
No,往往我们在开发产品的时候,UI和接口很难达到同步,这个时候MVP就派上用场了,如果界面出了,接口没出,我们是不是可以先把Activity和Presenter给实现了呢?等到接口出来,我们直接写Model层的代码就ok了,再也不需要傻傻的等着了。
有人说mvp会导致接口泛滥,但是你用了之后,不觉得多写两个接口就可以方便这么多,而且维护方便了不少么?
- Android MVP设计模式的最佳实现
- Android的MVP设计模式
- Android的设计模式MVP
- Android MVP 设计模式
- Android: MVP设计模式
- Android MVP 设计模式
- Android MVP设计模式的理解
- Android MVP模式实现
- Android中MVP模式的简单实现
- Android MVP模式的简单实现
- Kotlin实现MVP设计模式
- MVP模式在Android中的设计和实现
- Android MVP设计模式登录具体实现Material Design风格
- android MVP设计模式实践
- Android中的MVP设计模式
- Android之mvp设计模式
- 关于Android MVP设计模式
- Android MVP设计模式浅析
- Atom 编辑器在新的标签页(tab)打开文件
- 推荐系统第2周笔记
- MFC框架互操作机制记录
- 生成任意值到任意值的随机数
- 局部内部类之内部类和匿名内部类比较
- Android MVP设计模式的最佳实现
- NoSQL数据库介绍(7)
- 手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单
- Implementing Redlines(Android)
- AdoConnection连接池的使用
- 前端 Html 2
- 【原创】k8s源码分析-----Mux And Broadcaster
- 关于CGContextRef画图
- datatables使用记录