很久没写Blog了,这两年也积累了比较多的知识和总结。也实现了不少的业务,以及针对部分业务的优化,发现呢有些知识还是可以分享出去的,只是之前一直在纠结会不会被人看不起什么的,之后才发现多虑了。毕竟放出去之后,不同程序员的思维集合起来,也许这个框架还能发展得更加快速、稳定。

可能之后都会两天一更,或者一星期两篇文章这样的速度更新下下。

感慨不多说了,首先放出自己写的一个生命周期感知的MVP架构

(PS:当前的架构是直接运用到一个线上项目了,成果也颇丰,结合自己封装的BaseMVPActivity,BaseMVPFragment一套组件使用,也是美滋滋的。)

生命周期感知的MVP?幌子?还是单纯的MVP?

什么是MVP?能点进来的小伙伴我都相信你都用过MVP了。

至于什么是生命周期感知?先看看这样一个场景:

在Presenter层处理业务逻辑,多多少少会涉及到网络请求,假若你用的是OkHttp、抑或是Retrofit+RxJava作为网络请求,那么就会存在异步请求回调UI的情况,但是我们知道OkHttp他不是和Context生命周期绑定的(阅读源码),Retrofit+RxJava也是的,除非你自己加上了RxLifeCycle的组件支持,但是RxLifeCycle有个问题,我需要bindActivity,那么这个Activity怎么传递进去呢?

原本MVP的设计模式,就是让Presenter层是无法感知View层的Context存在的,假若打通了这个流程,无异于增加了MVP的复杂度。

以下是RxLifeCycle使用(这个bindActivity的对象需要怎么传递呢?)

myObservable.compose(RxLifecycleAndroid.bindActivity(lifecycle)).subscribe();

那么问题就来了,因为我Presenter层是不知道Activity或者Fragment的生命周期的,假若在请求回调的期间,我的Activity或者Fragment需要销毁了,但是由于请求回调占用着View层,那么我们的Activity和Fragment就出现了内存泄漏,内存多处泄漏的情况下,还可能直接出现空指针异常(因为泄漏的Activity部分的控件可能已经被回收了,但是继续调用View层控件。)那么App就直接crash掉了。

我们都知道OkHttp里面的请求是可以通过

OkHttpClient.dispatcher().cancelAll()

去取消请求,而Retrofit+Rxjava 就可以通过Observer中的onSubscribe函数,通过一个Disposable列表记录请求,然后在合适的时机去遍历取消就Ok了。

合适的时机?合适的时机在哪里了?

用脚趾头扣动了脑袋瓜想想,也就只有在Activity或者Fragment的onDestory回调的时候了。

时机找到了,生命周期怎么才能从View层传递到Presenter层呢?恰逢AndroidJetPack(后面迭代后改成AndroidX了)的诞生,使我有这个想法封装了一个LifeCycleMVP的框架。

Google地址:https://developer.android.com/jetpack/

因为公司可以翻墙,所以看的都是英文文档。关于JetPack的组件,我会另外开一个篇章去写。

LifeCycle作为Google JetPack 框架下的一个构建工具,Google也是心疼Android开发者,深知Android开发中Activity和Fragment生命管理的问题。特意除了一套LifeCycle供我们使用。

这上面的意思大概就是:LifeCycle是一个轻量的生命周期管理组件,通过监听回调的方式,实现生命周期的监听与回调。例如管理Activity和Fragment的生命回调。

实际上用着也很好用,很简单。因为在AppCompatActivity里面就支持了LifeCycle组件了。所以两三句代码就搞掂了生命周期的响应了

暂时先说下LifeCycle组件的三个类:

LifeCycleOwner:生命周期持有者,一个接口。用于提供生命周期相关回调(Activity的提供实现最后在一个叫SupportActivity,里面就实现了当前接口,用于提供当前LifeCycleOwner对象)

LifeCycleObserver:生命周期观察者,一个接口,用于实现并监听生命周期回调

LifeCycleRegistery:生命周期注册表,主要是关联生命持有者和观察者、控制事件回调给哪个观察者、生命周期绑定处理等。

详细的实现可以自己看看源码(不会很复杂),也可以跳转到这里:待补充

gradle引用:compile "android.arch.lifecycle:extensions:1.1.1"

前戏做足,现在就是撸代码的时刻了。

首先MVP开发模式中,我们先定义一套MVP层的协议,IBaseView,IBasePresenter。

定义一个IBaseView的接口先,可以用于统一管理View层对象。

实现什么函数无伤大雅,可以根据自己业务需求实现。

IBaseView.java

/*** @Author:Rayman* @Date:2018/10/17* @Description: View实现的接口*/
public interface IBaseView {/*** 显示错误,比如无数据、网络错误等等。** @param msg 错误文案提示*/void showErrorMsg(String msg);}

View层回调自己弄,Presenter层回调才是关键。Presenter层我定义的函数有四个:

绑定View、View层onCreate回调(考虑到有的P层需要用到该生命周期回调)、View层onDestroy回调、其他生命周期回调

IBasePresenter.java

/*** @Author:Rayman* @Date:2018/10/17* @Description:Presenter的接口 .* 默认实现AndroidX LifeCycle组件**/
public interface IBasePresenter<T> extends LifecycleObserver {/*** 绑定View** @param view*/void setView(@NonNull T view);/*** View层OnCreate事件回调*/@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)void onViewCreate();/*** View层onDestroy事件回调*/@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)void onViewDestroy();/*** 生命周期切换时候回调*/@OnLifecycleEvent(Lifecycle.Event.ON_ANY)void onLifeCycleChange(@NonNull LifecycleOwner owner,@NonNull Lifecycle.Event event);}

按照上面定义完成之后,初步的LifeCycleMvp框架是出来了,剩下的就是怎么走一个MVP的流程和怎么实现生命周期的绑定。

绑定生命周期

绑定生命周期这个呢~需要配合BaseActivity或者BaseFragment使用。

我这里就放出一个BaseMVPActivity,其他情况的使用也是如此。

主要是继承了BaseActivity,然后实现了IBaseView接口,内部还创建了一个IBasePresenter的成员变量。

然后在onCreate生命周期回调的时候,进行View层和Presenter的绑定,同时也绑定生命周期

/*** @Author:Rayman* @Date:2018/10/17* @Description:继承BaseActivity,整合MVP架构*/public abstract class BaseMvpActivity<D> extends BaseActivity implements IBaseView<D> {/*** description:MVP层关联**/private IBasePresenter mPresenter;@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {initMvp();super.onCreate(savedInstanceState);}/*** 初始化MVP架构*/private void initMvp() {mPresenter = createPresenter();if (mPresenter != null) {mPresenter.setView(this);// 初始化MVP的时候,添加生命周期监听getLifecycle().addObserver(mPresenter);}}/*** 设置当前模块的P层,需要在initView之前调用** @return*/protected abstract IBasePresenter createPresenter();}

生命周期绑定之后,就剩下使用了。

如何使用?

首先实现一个业务逻辑的Presenter层,然后继承IBasePresenter。

为了方便演示,我随便拿了项目的一个Contract类

IUserChangeAccountContract.java

/*** @Author:Rayman* @Date:2018/10/21* @Description:用户模块---更换账号*/
public interface IUserChangeAccountContract {interface IUserChangeAccountModel {/*** description:更换账号**/Observable<CommonData> changeAccount(String realName , String account);}interface IUserChangeAccountPresenter extends IBasePresenter<IUserBindAliAccountView> {void changeAccount(String realName , String account);}// 当前这个IBaseLoadingView也是继承IBaseView的。interface IUserChangeAccountView extends IBaseLoadingView<CommonData> {void changeAccountSuccess(String msg);}}

然后再看看IUserChangeAccountPresenter的实现

UserChangeAccountPresenter.java

/*** @Author:Rayman* @Date:2018/10/21* @Description:用户模块---P层---更换账号*/
public class UserBindAliAccountPresenter implements IUserBindAliAccountContract.IUserBindAliAccountPresenter {private IUserBindAliAccountContract.IUserBindAliAccountView mView;private IUserBindAliAccountContract.IUserBindAliAccountModel mModel = new UserBindAliAccountModel();private ArrayList<Disposable> mDisposableList = new ArrayList();private int requestCount = 0;@Overridepublic void setView(IUserBindAliAccountContract.IUserBindAliAccountView view) {mView = view;}@Overridepublic void onViewCreate() {LogUtils.error("View创建");}@Overridepublic void onViewDestroy() {for(int i = 0,size = mDisposableList.size();i < size; i++){Disposable disposed = mDisposableList.get(i);disposed.dispose();}LogUtils.error("View销毁请求:" + requestCount);}@Overridepublic void onLifeCycleChange(LifecycleOwner owner, Lifecycle.Event event) {LogUtils.error("View生命周期变换:" + event.name());}@Overridepublic void changeAccount(String realName,String account) {mView.showLoading();requestCount++;mModel.changeAccount(realName, account).subscribe(new RxSubscriber<CommonData, IUserBindAliAccountContract.IUserBindAliAccountView>(mView) {@Overridepublic void onSubscribe(Disposable d) {super.onSubscribe(d);mDisposableList.add(d);}@Overridepublic void onNext(CommonData t) {super.onNext(t);mView.bindAliAccountSuccess("绑定成功");UserUtils.updateBindAccount(account, realName);}});}
}

整个流程就是这样了,上面的例子我就是用Retrofit+RxJava的方式请求的。然后在onSubscribe中将RxJava的事件处理添加到一个列表,然后在ViewDestroy的时候遍历销毁。

最后我们来看下Log的输出还有通过AndroidProfiler查看下,多个请求是否会引起Activity内存泄漏。

待补充----

好了~代码就上面所述的,联动下一篇---基于LifeCycleMvp再扩展,然后发布一个GitHub的开源库。

打造一个生命周期感知的MVP架构相关推荐

  1. Lifecycle Activity和Fragment生命周期感知组件 LifecycleObserver MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. 一文,教你打造员工生命周期解决方案

    伴随着移动互联网.人工智能.云计算等技术的发展,企业的信息化建设增速,业务系统.员工规模不断壮大.企业渐渐从传统的本地架构向云端迁移,面临着人员流动性增加,所需应用系统只增不减.种类繁多的困境,身份信 ...

  3. Servlet生命周期与Web容器架构及处理请求详解

    一.Servlet对象 Servlet对象运行在Servlet容器中,Servlet的生命周期由容器管理(Servlet容器的基本思想是在服务器端使用Java来动态生成网页). (一)Servlet对 ...

  4. Android-Lifecycle超能解析-生命周期的那些事儿

    版权声明:本文已授权微信公众号:Android必修课,转载请申明出处 众所周知,Android凡是需要展示给用户看的,都包含着生命周期这个概念,例如Activity.Fragment.View等都与生 ...

  5. android代理生命周期,了解 Activity 生命周期

    当用户浏览.退出和返回到您的应用时,您应用中的 在生命周期回调方法中,您可以声明用户离开和再次进入 Activity 时 Activity 的行为方式.例如,如果您正构建流媒体视频播放器,当用户切换至 ...

  6. mvp关联activity生命周期_Android MVP架构从入门到精通-真枪实弹

    Android MVP架构从入门到精通-真枪实弹 一. 前言 你是否遇到过Activity/Fragment中成百上千行代码,完全无法维护,看着头疼? 你是否遇到过因后台接口还未写而你不能先写代码逻辑 ...

  7. android mvvm livedata_再谈Android应用架构——Jetpack VS 生命周期

    前面我们对MVC.MVP.MVVM进行了详尽的分析,但还有一个问题悬而未决,那就是生命周期.在Android平台上生命周期具有十分重要的意义,因此这也是架构必须考虑的因素之一.生命周期处理不好很容易发 ...

  8. Android官方开发文档Training系列课程中文版:管理Activity的生命周期之启动一个Activity

    原文地址 : http://android.xsoftlab.net/training/basics/activity-lifecycle/index.html 导言 用户通过导航退出或者返回应用的时 ...

  9. 软工导第一节课 计算机软件工程学作一个简短的概述,回顾计算机系统发展简史 软件工程的基本原理和方法有概括的本质的认识,详细讲解生命周期相关知识讲解8种典型的软件过程模型

    文章目录 软件危机 软件的定义 软件危机典型表现 产生软件危机的原因 消除软件危机的方法 软件工程 什么是软件工程 软件工程的本质特征 软件工程的基本原理 软件工程方法学 传统方法学 面向对象方法学 ...

最新文章

  1. [Java]ping或扫描端口的工具类
  2. CentOs7中resourcemanager启动不了
  3. 通过远程桌面操作程序出现hook cannot be created(SendKeys语句错误)的解决
  4. FreeSWITCH中文语音包
  5. Vue学习(watch、computed、生命周期、filter)- 学习笔记
  6. en55032最新标准下载_大型设备塔吊安装维保、安全检查及案例,94页PPT下载!
  7. .NET开发中应该遵循的几点建议
  8. 面试题4,打印出100-999所有的“水仙花数”。
  9. python安装 + pycharm安装和入门学习 +安装配置TensorFlow
  10. hadoop10---消息队列
  11. 【STM32F429】第5章 ThreadX NetXDUO网络协议栈介绍
  12. WinForm中Chart控件使用
  13. 简单介绍谷歌关键词扩展工具
  14. matlab线性方程组画图,线性方程组求解在Excel和Matlab中的实现
  15. 每日新闻丨IBM发布全新高端存储
  16. win10多用户同时远程桌面登陆Termsrv.dll(允许多个RDP会话)-win10最新2004版。
  17. Python视频图像播放中加入文字
  18. python二级题库 第四套 附刷题软件
  19. 华为云IoT智慧物流案例04 | 4G网卡拨号(广和通L610-CAT.1模组)与北斗定位模组(中科微电子)数据解析
  20. 员工办事指南(社保公积金)

热门文章

  1. eNSP配置(直连/静态/动态路由,DHCP,单臂路由,ACL,NAT,链路聚合,负载均衡,WLAN,备份路由)
  2. Redis(三)【五大数据类型三种特殊数据类型】
  3. 做网赚想要赚到钱,心态很重要
  4. 用python可以画的可爱的图形_用Python的Turtple画图形
  5. VS2017中创建使用 XRM 工具常用登录控件的WPF应用程序,适用CRM9.X版本
  6. python测试开发教程 龙腾_龙腾源码网京东 有货自动下单,Python 脚本 你的口罩...
  7. R语言建立神经网络过程
  8. Selenium等待机制之显示等待
  9. 流程审批类系统数据库结构怎么定义
  10. 《惢客创业日记》2019.02.22(周五) 先僵化,后优化,再固化