Android---MVP 中 presenter 声明周期的管理

我们经常在 Android MVP 架构中的 Presenter 层做一些耗时操作,比如请求网络数据,然后根据请求后的结果刷新 View。但是,如果按返回结束 Activity,而 Presenter 依然在执行耗时操作。那么就有可能造成内存泄漏,严重时甚至会造成程序崩溃。因为 Presenter 中的 View 已经变为 null。

为了解决这个问题,需要将 Activity 的某些生命周期方法与 Presenter 保持一致

Lifecycle 绑定 presenter 生命周期

Lifecycle 的使用很简单,Activity 通过继承 AppCompatActivity 会自动继承来自父类 ComponentActivity 的方法 getLifeCycle。具体如下

onStateChanged 方法会在 Activity 的生命周期发生变化时被触发,比如当我们打开 LoginActivity 时就会显示如下日志

当中 LoginActivity 界面按下返回键,则打印如下内容

Lifecycle 还提供了注解的方式使用,因此我们可以很容易创建一个接口 IPresenter。在这个接口中声明对各种 Activity 声明周期的回调,如下所示

上图中 IPresenter 接口通过注解的方式将 Activity 的声明周期绑定到相应的方法上。我们只需要在 BsetPresenter 中实现上述方法,并在方法中数据绑定与取消的操作即可,具体如下

注意:上图中代码存在一些问题,使用了 Android 中的 Log 来打印日志信息。严格来说,在 Presenter 层应该禁止出现任何 Android 中的类。这里为了快速演示效果,所以直接使用 Log 打印日志。

接下来,修改 LoginActivity,将 BasePresenter 注册到 LifeCycle 中即可,如下代码所示

从新打开 LoginActivity,显示日志如下

关闭 LoginActivity,显示日志如下

可以看出,当 Activity 执行 onDestory() 时,BasePresenter 的 onDestory() 方法也会被执行。

在 LoginActivity 方法中有 login() 方法,此方法会执行 BasePresenter 中的 login() 方法。如下代码

在 BasePresenter 中的 login() 方法中模拟执行了一段耗时操作。如果在 Activity onDestory() 时,BasePresenter 还没有处理完耗时操作,则会造成内存泄漏。 

解决办法就是在 BasePresenter 的 onDestory 方法中停止正在执行的耗时操作。如下所示

合理使用 Presenter 生命周期

并不是所有的 Activity 的生命周期都需要通知 Presenter。举个例子,假如我们需求是根据 GPS 定位,展示用户的位置。但是为了节省电量,有可能会在灭屏之后,解绑定 GPS 定位的接收事件。

如果使用 MVP 架构,需要有一个 TrackingActivity 实现 MVP 的接口 TrackingView,并在生命周期方法中调用 presenter 的相应方法。如下所示

TrackingPresenter 是 presenter 层的实现,内部实现了 GPS 定位的监听事件,并分别在 resume 和 stop 方法中绑定和解绑定 GPS。如下

上述写法是常规的 MVP 写法,但是存在两个问题:1)GpsTracker 实际的控制周期是跟 Activity 有关的,因为亮屏和灭屏事件是在 Activity 中接收的。中间多了一层 Presenter 层其实是多余的;2)从重构的角度看,TrackingPresenter 其实违反了职责单一原则(Single Responsibility)。因为 Presenter 层的主要作用是用来刷新 View,但是上述代码中的 TrackingPresenter 还负责对 GpsTracker 进行管理。

这种情况下,我们可以将 GpsTracker 初始化在 Activity 中,将 GpsTracker 的绑定与解绑定都在 Activity 中管理,最后将 GpsTracker 传给 TrackingPresenter 执行业务上的逻辑。具体实现如下

TrackingActivity 中对 tracker 进行管理,并且根据 Presenter 层的逻辑处理,回调 showCurrentPosition() 方法。

TrackingPresenter 

TrackingPresenter 只负责对 Gps 事件的监听并根据结果刷新 View。这样 View 层和 Presenter 层的职责单一原则就完咋。在完成实际需求的前提下,也丝毫不影响 Presenter 层的单元测试

当然,并没有绝对正确或错误的架构,说到底代码具体要怎样写、功能具体应该怎样实现,最终还是要看实际业务场景。

总结

主要对 MVP 架构中 Presenter 层的使用做了2点优化介绍:

1. 如何支持 Presenter 的生命周期,使其在 Activity 被销毁时也能取消相应的耗时请求。

2. 合理使用 Presenter 的生命周期,Activity 中所有的方法都委托给 Presenter 来处理是不合理的。这样会造成 Presenter 层极其庞大,也难以维护,有时也会违反职责单一原则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/187763.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RustRover里使用AI通义灵码来写代码

AI通义灵码我选择RustRover里的 plugin进行下载使用 然后我们就提问好了&#xff1a;让他用c语言写一个冒泡排序程序 #include <stdio.h>void bubble_sort(int arr[], int size) {int i, j, temp;for (i 0; i < size - 1; i) {for (j 0; j < size - i - 1; j) {i…

Hololens开发笔记

1、关闭阴影 2、将相机渲染改为后向。因为默认是Forward&#xff0c;当在场景里面想使用点光源时&#xff0c;运行起来三角面会翻倍&#xff0c;影响软件运行流畅度。 3、第三人称同步相关。开启Host/Sever/Client前&#xff0c;需要将所有挂有NetworkObject/NetworkTransfor…

VINS-Mono-后端优化 (三:视觉雅可比推导)

用逆深度是因为这样可以在优化中从优化3个变量降低到1个&#xff0c;降低优化的维度加快求解速度 用逆深度是因为当距离很远的时候&#xff0c; 1 x \frac{1}{x} x1​ x x x 就会无穷大&#xff0c;而3D点很近的情况也一般不会有&#xff0c;这也是为了数值稳定性 用逆深度的…

Android 图层列表 、 LayerDrawable 、 layer-list \ 改变 seekbar thumb 滑块 的颜色

android 官网 &#xff1a; 图层列表 LayerDrawable / layer-list LayerDrawable 是管理其他可绘制对象数组的可绘制对象。列表中的每个可绘制对象均按照列表顺序绘制。列表中的最后一个可绘制对象绘于顶部。 每个可绘制对象均由单个 <layer-list> 元素内的 <item>…

树之二叉排序树(二叉搜索树)

什么是排序树 说一下普通二叉树可不是左小右大的 插入的新节点是以叶子形式进行插入的 二叉排序树的中序遍历结果是一个升序的序列 下面是两个典型的二叉排序树 二叉排序树的操作 构造树的过程即是对无序序列进行排序的过程。 存储结构 通常采用二叉链表作为存储结构 不能 …

内网如何使用Python第三方库包(举例JustinScorecardPy)

内网如何使用Python第三方库包 一、下载python whl文件(官网有的) 1、第一种方法 要直接下载whl文件&#xff0c;你可以按照以下步骤操作&#xff1a; 首先&#xff0c;访问 https://pypi.org/ 或 https://www.lfd.uci.edu/~gohlke/pythonlibs/ 网站。这两个都是Python的官方…

光刻掩膜版怎么制作的?

光掩膜版基本上是 IC 设计的“主模板”。掩模版有不同的尺寸。常见尺寸为 6 x 6 英寸一般的掩膜版由石英或玻璃基板组成。光掩膜版涂有不透明薄膜。更复杂的掩模版使用其他材料。 一般来说&#xff0c;术语“photo mask”用于描述与 1X 步进机或光刻系统一起使用的“主模板”。…

希尔排序原理

目录&#xff1a; 一、希尔排序与插入排序 1&#xff09;希尔排序的概念 2&#xff09;插入排序实现 二、希尔排序实现 一、希尔排序与插入排序 1&#xff09;希尔排序的概念 希尔排序(Shells Sort)是插入排序的一种又称“缩小增量排序”&#xff08;Diminishing Incremen…

ElasticSearch7.x - HTTP 操作 - 索引操作

创建索引 对比关系型数据库,创建索引就等同于创建数据库 在 Postman 中,向 ES 服务器发 PUT 请求 :http://192.168.254.101:9200/shopping 说明 {"acknowledged"【响应结果】: true, # true 操作成功"shards_acknowledged"【分片结果】: true, # 分片操…

紧急事件,停电导致安森美韩国厂全线停工 | 百能云芯

11月9日的消息报道&#xff0c;全球半导体公司安森美遭遇了一场意外的停电事故&#xff0c;发生在位于韩国的富川晶圆厂&#xff0c;导致整个工厂陷入停工状态&#xff01; 停电事件发生在11月5日&#xff0c;导致富川晶圆厂的产线暂时停工&#xff0c;停电持续了大约20分钟。由…

Mac电脑Visio文件编辑查看软件推荐Visio Viewer for Mac

mac版Visio Viewer功能特色 在Mac OS X上查看Visio绘图和图表 在Mac OS X上轻松查看MS Visio文件 在Mac上快速方便地打开并阅读Visio文件&#xff08;.vsd&#xff0c;.vsdx&#xff09;。 支持通过放大&#xff0c;缩小&#xff0c;旋转&#xff0c;文本选择和复制&#xff0…

DSP开发例程(4): logbuf_print_to_uart

目录 DSP开发例程: logbuf_print_to_uart新建工程源码编辑app.cfgos.cmain.c 调试说明 DSP开发例程: logbuf_print_to_uart SYS/BIOS 提供了 xdc.runtime.Log, xdc.runtime.LoggerBuf 和 xdc.runtime.LoggerSys 这几个模块用于日志记录. 日志信息在 应用程序调试和状态监控中非…

第二十九章 目标检测中的测试模型评价指标(车道线感知)

前言 近期参与到了手写AI的车道线检测的学习中去&#xff0c;以此系列笔记记录学习与思考的全过程。车道线检测系列会持续更新&#xff0c;力求完整精炼&#xff0c;引人启示。所需前期知识&#xff0c;可以结合手写AI进行系统的学习。 介绍 自动驾驶的一大前提是保证人的安全…

中国智能驾驶的“突围赛”打响,这家本土厂商为何能成为“先行者”?

中国本土厂商正在成为全球智能汽车产业链的“核心力量”。 根据《高工智能汽车研究院》数据显示&#xff0c;今年1-6月&#xff0c;自主品牌标配L2&#xff08;含L2&#xff09;级辅助驾驶交付新车155.34万辆。其中&#xff0c;搭载中国本土智能驾驶解决方案提供商&#xff08…

Nacos使用指南

Nacos使用指南 1.认识Nacos Nacos是SpringCloudAlibaba的一个组件&#xff0c;遵循SpringCloud规范 2.Nacos的优势 1.支持服务端主动检测服务提供者状态。临时实例采用心跳检测&#xff0c;非临时实例采用主动检测 2.Nacos支持服务列表变更消息推送&#xff0c;消息更加及…

C++入门篇3(类和对象【重点】)

文章目录 C入门篇3&#xff08;类和对象【重点】&#xff09;1、面向过程和面向对象2、类的引入3、类的定义4、类的访问限定符及封装4.1、访问限定符4.2、封装 5、类的作用域6、类的实例化&#xff08;对象&#xff09;7、类对象模型7.1、类对象的存储方式7.2、结构体&#xff…

mysql索引下推

文章目录 什么是索引下推索引下推优化的原理索引下推的具体实践没有使用ICP使用ICP 总结索引下推使用条件相关系统参数 什么是索引下推 索引下推(Index Condition Pushdown&#xff0c;简称ICP)&#xff0c;是MySQL5.6版本的新特性&#xff0c;它能减少回表查询次数&#xff0…

【Proteus仿真】【51单片机】汽车尾灯控制设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用按键、LED模块等。 主要功能&#xff1a; 系统运行后&#xff0c;系统运行后&#xff0c;系统开始运行&#xff0c;K1键控制左转向灯&#xff1b;…

C# .NET Core API 注入Swagger

C# .NET Core API 注入Swagger 环境 Windows 10Visual Studio 2019(2017就有可以集中发布到publish目录的功能了吧)C#.NET Core 可跨平台发布代码,超级奈斯NuGet 套件管理dll将方法封装(据说可以提高效率,就像是我们用的dll那种感觉)Swagger 让接口可视化编写时间2020-12-09 …

MySQL on duplicate key update用法

基本使用方法 public static final String SQL_TQI_SINK "insert into " ConfigureContext.get(ConfigKeyConstants.MYSQL_TABLE_TQI) " \n" "(mile_km, mile_start_km, mile_start_m, is_out, tqi_alig_l, \n" "tqi_alig_r, tqi_surf_l…