著论准过秦,作赋拟子虚。这篇文章主要讲述Android架构篇--MVP模式的介绍篇相关的知识,希望能为你提供帮助。
摘要:
在MVVM成熟之前MVP模式在android上有被神化的趋势,笔者曾经在商业项目中从零开始大规模采用过MVP模式对项目进行开发。在使用MVP模式进行开发的时候发现项目的结构模式对开发是有一定的影响的,在这里笔者会对这一问题进行探讨。希望通过这篇blog能让读者了解如何使用MVP模式搭建一个功能完善的MVP模式开发框架,避免一些笔者认为比较严重的问题。
为什么要使用MVP模式在传统的Android开发中,我们一般是使用MVC模式进行开发的。
传统MVC模式介绍:
- View: 视图层,对应xml文件
- Controller: 控制层,对应Activity和Fragment层,进行数据处理
- Model:实体层,负责获取实体数据
MVP模式介绍:
- View: 视图层,对应xml文件与Activity/Fragment
- Presenter: 逻辑控制层,同时持有View和Model对象
- Model: 实体层,负责获取实体数据
文章图片
MVP模式图解
采用MVP模式的优势是:
- 把业务逻辑抽离到Presenter层中,View层专注于UI的处理。
- 分离视图逻辑与业务逻辑,达到解耦的目的。
- 提高代码的阅读性。
- Presenter被抽象成接口,可以根据Presenter的实现方式进行单元测试。
- 可拓展性强。
- 项目结构会对后期的开发和维护有一定的影响。具体视APP的体量而定。
- 代码量会增多,如何避免编写过多功能相似的重复代码是使用MVP开发的一个重点要处理的问题。
- 有一定的学习成本。
Android上MVP模式的简单应用先来看看一个简单用mvp模式模拟登陆的demo,下面的示例代码和其它简单介绍MVP模式的代码没有太大区别。如果有了解过的同学可以直接跳过看下一章关于如何优化MVP模式的结构的文章。
下面我们来看看在Android上用MVP模式实现简单的登录逻辑的方式:
. 登陆界面
文章图片
登陆界面
- 项目的结构:
文章图片
项目结构
. 代码实现说了这么多,最后我们来看看代码的实现吧。
- ILoginModel
1 2 3 public interface ILoginModel { void login(String name ,String password); } - ILoginPresenter
1 2 3 4 5 6 public interface ILoginPresenter { void loginToServer(String userName,String password); void loginSucceed(); } - ILoginView
1 2 3 4 5 6 public interface ILoginView { void showProgress(boolean enable); void showLoginView(); }
ILoginModel.login(String name ,String password)
登陆方法,通过该方法向服务器发送登陆请求。ILoginPresenter. loginToServer (String name ,String password)
通知Model响应登陆事件。ILoginPresenter. loginSucceed()
当登陆事件完成时(成功/失败),Model层要通知该方法登陆事件已完成。ILoginView. showProgress(boolean enable)
当Presenter层调用loginToServer (String name ,String password)
方法时,要通过该方法通知View层显示加载动画。ILoginView. showLoginView()
登陆成功时,Presenter层会通过该方法通知View层登陆已成功。
- LoginModel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class LoginModel implements ILoginModel{ private ILoginPresenter presenter; private Handler mHandler = new Handler(); public LoginModel(ILoginPresenter presenter) { this.presenter = presenter; } @Override public void login(String name ,String password) { mHandler.postDelayed(new Runnable() { @Override public void run() { Log.d("LoginModel", "run: "); presenter.loginSucceed(); } },2000); } }
login(String name,Stringpassword)
登陆方法,该方法的具体实现逻辑是通过线程休眠2秒来模拟网络登陆的过程,登陆成功后会通过LoginPresenter的loginSucceed()
方法来通知Presenter层登陆结果。实际开发中我们需要根据具体的业务逻辑来实现该过程。- LoginPresenter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class LoginPresenter implements ILoginPresenter{ private ILoginModel loginModel; private ILoginView loginView; public LoginPresenter(ILoginView loginView) { this.loginView = loginView; this.loginModel = new LoginModel(this); } @Override public void loginToServer(String userName, String password) { loginView.showProgress(true); loginModel.login(userName,password); } @Override public void loginSucceed() { loginView.showProgress(false); loginView.showLoginView(); } }
loginToServer(String userName, String password)
方法成功时,通知View层显示加载动画并调用ILoginModel层的login(String userName, String password)
方法向服务器发送登陆请求。当登陆成功后(即Model层通知loginSucceed方法时)通过loginView.showProgress(false)
方法通知View层隐藏加载动画,并通知View登陆成功。- LoginActivity
对于LoginActivity我们只需要关注其中的几个方法即可1 2 3 4 5 6 7 loginBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //模拟登陆,不需要账号密码 loginPresenter.loginToServer("",""); } });
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Override public void showProgress(boolean enable) { if (enable){ progressBar.setVisibility(View.VISIBLE); loginLayout.setVisibility(View.GONE); }else { progressBar.setVisibility(View.GONE); loginLayout.setVisibility(View.VISIBLE); } } @Override public void showLoginView() { Toast.makeText(LoginActivity.this,"登陆功",Toast.LENGTHSHORT).show(); finish(); } |
结合上面的代码可以看出,当点击登陆按钮的监听事件时,我们不需要关注业务逻辑,只需要调用
loginPresenter.loginToServer("","");
方法即可,然后根据实际情况实现View层中ILoginView接口的方法即可,这样达到了UI业务与逻辑完全分离的目的。推荐阅读
- android studio 环境配置及使用时遇到的问题
- Android 动态渐变按钮
- android修改getprop读取到的ro.build.fingerprint属性
- Android 密钥保护和 C/S 网络传输安全理论指南
- Android 2018最新的三方库
- [Angular] Extract Implementation Details of ngrx from an Angular Application with the Facade Pattern
- android recovery代码修改之原生建议
- web测试和app测试的区别
- App Technical Support For "心味美食"