词条信息

admin
admin
超级管理员
词条创建者 发短消息   

相关词条

热门词条

更多>>
什么是端口?到底是做什么的呢?
端口一般指两种,一种是硬件比如路由器或者交换机的插网线的端口,一种是软件的逻辑的概念,比如http的80端口!...
7种进阶方法让你快速测试端口连通性
Ping是Windows、Linux和Unix系统下的一个检查网络连通性的命令工具,对于大部分互联网用户来说很...
电脑开机,总需要按F1,是什么原因造成的?
一.主板掉电这个说法是行业内的叫法了,一般是主板的CMOS电池没电了导致的。也是最常见的一种提示你按F1的提示...
社保降费对个人有什么影响?
下调城镇职工基本养老保险单位缴费比例是政府给企业发的一个大红包,特别是对于企业来说是一个利好,但是对个人来说有...
车辆“出险”对下年保费的影响,到底有多大?
【出险对交强险的影响】【出险对商业险的影响】车辆“出险”对下年保费的影响,到底有多大?这里有必要先提下车险第三...

精选图集

更多>>
简易百科旧版 >>所属分类 >> Android   

Android MVP 架构

标签: Android MVP 架构

顶[0] 发表评论(0) 编辑词条

本Demo使用 Okhttp3、Retrofit2、Rxjava2 ,使用AutoDispose解决RxJava内存泄漏

Github:

https://github.com/RookieExaminer/MvpDemo


什么是 MVP,为什么要用MVP?


网上介绍MVP的很多,百度一下你就知道,至于为什么要用MVP,当然是由于它的优势了:


1、代码简洁

此处的简洁是逻辑的简洁,而不是代码本身 举个栗子


比如购物车界面,有很多请求网络的地方:获取购物车商品列表、购物车商品的删除、购物车商品的购买等等, 这么多网络请求,如果都写在一个 Activity,而且还有大量逻辑判断,那这个 Activity的行数~ 看着就让人头痛, 即便写了注释,维护起来也是比较麻烦的


2.降低耦合,方便维护

MVP的使用,使Activity中的网络请求剥离出来 成为model、presenter,model只负责网络的请求、pesenter负责处理请求网络后的数据处理:加载中 成功 or 失败 取消加载;最后View进行界面的展示



Start 看图:


嗯哼? 不是 Model、Presenter、View这三个 么,怎么又多出来个Contract,这又是什么鬼?

这就涉及到MVP的缺点了,正所谓,金无足赤,人无完人,MVP既然有优点当然也有它的缺点了

MVP在实现代码简洁的同时,额外增加了大量的接口、类,不方便进行管理,于是Contract 就登场了。

Contract 百度翻译 : 合同;契约;协议

Contract 如其名,是一个契约,将 Model、View、Presenter 进行约束管理,方便后期类的查找、维护。

下面演示下登陆的MVP实现方式

(示例代码由开发项目中剥离到Demo中,登陆接口使用的是玩安卓的登陆API:http://www.wanandroid.com/blog/show/2)

首先,创建一个登陆的Contract:

publicinterfaceMainContract{

interfaceModel{ }

interfaceViewextendsBaseView{ }

interfacePresenter{ }

}

其次创建 Presenter、Model、View 对应 Contract 中的接口;

publicclassMainPresenterimplementsMainContract.Model{}

publicclassMainModelimplementsMainContract.Presenter{}

publicclassMainActivityimplementsMainContract.View{}

完整的 Contract:

publicinterfaceMainContract{

interfaceModel{

Flowable<BaseObjectBean<LoginBean>> login(String username, String password);

}

interfaceViewextendsBaseView{

@Override

voidshowLoading();

@Override

voidhideLoading();

@Override

void(Throwable throwable);

voidonSuccess(BaseObjectBean<LoginBean> bean);

}

interfacePresenter{

/**

* 登陆

*

* @paramusername

* @parampassword

*/

voidlogin(String username, String password);

}

}

在 MainContract 中

  • Model接口: 创建对应的联网请求的方法,将 Presenter 提交的字段放到联网请求中,发送给服务器
  • View接口: 创建在界面上显示加载中、取消加载以及登陆成功、失败的方法
  • Presenter接口: 创建 登陆的方法,以及需要提交的字段 (username、password)

MainModel的完整代码:

publicclassMainModelimplementsMainContract.Model{

@Override

publicFlowable<BaseObjectBean<LoginBean>> login(String username, String password) {

returnRetrofitClient.getInstance().getApi().login(username,password);

}

}

Model 类实现 MainContract.Model 接口中的 login(String username, String password)方法,将 username、password 放在联网请求中,进行请求服务器。

MainView 的完整代码:

publicclassMainActivityextendsBaseMvpActivity<MainPresenter> implementsMainContract.View{

@BindView(R.id.et_username_login)

TextInputEditText etUsernameLogin;

@BindView(R.id.et_password_login)

TextInputEditText etPasswordLogin;

@Override

publicintgetLayoutId(){

returnR.layout.activity_main;

}

@Override

publicvoidinitView(){

mPresenter = newMainPresenter();

mPresenter.attachView(this);

}

/**

* @return帐号

*/

privateString getUsername(){

returnetUsernameLogin.getText().toString().trim();

}

/**

* @return密码

*/

privateString getPassword(){

returnetPasswordLogin.getText().toString().trim();

}

@Override

publicvoidonSuccess(BaseObjectBean bean){

Toast.makeText(this, bean.getErrorMsg(), Toast.LENGTH_SHORT).show();

}

@Override

publicvoidshowLoading(){

ProgressDialog.getInstance().show(this);

}

@Override

publicvoidhideLoading(){

ProgressDialog.getInstance().dismiss();

}

@Override

publicvoid(Throwable throwable){

}

@Override

protectedvoidonCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

// TODO:add setContentView(...) invocation

ButterKnife.bind(this);

}

@OnClick(R.id.btn_signin_login)

publicvoidonViewClicked(){

if(getUsername().isEmpty() || getPassword().isEmpty()) {

Toast.makeText(this, "帐号密码不能为空", Toast.LENGTH_SHORT).show();

return;

}

mPresenter.login(getUsername(), getPassword());

}

}

MainActivity 中实现 MainContract.View中的方法 ,在实现的方法中,进行进度条加载、和登陆成功or失败的UI的展示:

@Override

voidshowLoading();

@Override

voidhideLoading();

@Override

void(Throwable throwable);

voidonSuccess(BaseObjectBean<LoginBean> bean);


MainPresenter 的完整代码:

publicclassMainPresenterextendsBasePresenter<MainContract.View> implementsMainContract.Presenter{

privateMainContract.Model model;

publicMainPresenter(){

model = newMainModel();

}

@Override

publicvoidlogin(String username, String password){

if(!isViewAttached()) {

return;

}

mView.showLoading();

model.login(username, password)

.compose(RxScheduler.<BaseObjectBean<LoginBean>>Flo_io_main())

.as(mView.<BaseObjectBean<LoginBean>>bindAutoDispose())

.subscribe(newConsumer<BaseObjectBean<LoginBean>>() {

@Override

publicvoidaccept(BaseObjectBean<LoginBean> bean)throwsException {

mView.onSuccess(bean);

mView.hideLoading();

}

}, newConsumer<Throwable>() {

@Override

publicvoidaccept(Throwable throwable)throwsException {

mView.(throwable);

mView.hideLoading();

}

});

}

}

MainPresenter 实现 MainContract.Presenter 接口中的 login(String username, String password) 方法

实例化Model,在 MainPresenter login(String username, String password)方法中,调用 model的网络请求,将 username、password 放在model 的 login() 方法中,进行请求服务器。

请求服务器前 使用 MainContract.View 中的 mView.showLoading()方法,进行显示加载中;在成功失败的回调中,使用对应的方法,以及取消加载。

其中BasePresenter、BaseView 是对Presenter以及View进行的封装

BaseView类:

publicinterfaceBaseView{

/**

* 显示加载中

*/

voidshowLoading();

/**

* 隐藏加载

*/

voidhideLoading();

/**

* 数据获取失败

* @paramthrowable

*/

void(Throwable throwable);

/**

* 绑定Android生命周期 防止RxJava内存泄漏

*

* @param<T>

* @return

*/

<T> AutoDisposeConverter<T> bindAutoDispose();

}

至于为什么不把 onSuccess()方法也封装,是因为请求网络,服务器返回的值是不一样的,在 Contract > View 接口中根据 bean 类设置 onSuccess()

BasePresenter类:

publicclassBasePresenter<VextendsBaseView> {

protectedV mView;

/**

* 绑定view,一般在初始化中调用该方法

*

* @paramview view

*/

publicvoidattachView(V view){

this.mView = view;

}

/**

* 解除绑定view,一般在onDestroy中调用

*/

publicvoiddetachView(){

this.mView = null;

}

/**

* View是否绑定

*

* @return

*/

publicbooleanisViewAttached(){

returnmView != null;

}

}

时间有限,暂时就先这样,具体可下载 Demo查看 ↓


本Demo:https://github.com/RookieExaminer/MvpDemo

MVP快速生成类的插件:https://github.com/githubwing/MVPHelper


参考:


Android MVP架构搭建:http://www.jcodecraeer.com/a/anzhuokaifa/2017/1020/8625.html?1508484926

Android架构中添加AutoDispose解决RxJava内存泄漏:https://www.jianshu.com/p/8490d9383ba5

 

 

附件列表


按字母顺序浏览:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

→我们致力于为广大网民解决所遇到的各种电脑技术问题
 如果您认为本词条还有待完善,请 编辑词条

上一篇Android性能优化之内存泄露
下一篇我理解的 iOS 与 Android 的区别

0
1. 本站部分内容来自互联网,如有任何版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
2. 本站内容仅供参考,如果您需要解决具体问题,建议您咨询相关领域专业人士。
3. 如果您没有找到需要的百科词条,您可以到百科问答提问或创建词条,等待高手解答。

关于本词条的提问

查看全部/我要提问>>