我的编程空间,编程开发者的网络收藏夹
学习永远不晚

协程作用域概念迭代RxTask 实现自主控制

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

协程作用域概念迭代RxTask 实现自主控制

结合协程作用域概念迭代 RxTask 实现作用域功能

在过去的一段时间里有幸接触过某个项目,整体技术方案落后且线程滥用导致出现大量的内存泄漏或者资源反复耗费。原因在于这个项目中对 RxJava 创建操作不规范,反复创建线程且不及时消耗导致,刚好朋友在使用我的 RxTask 开源项目中也给我反馈一件事,能否提供一个类似像协程作用域概念,当被告知需要消耗时则及时把 RxTask 销毁。故此针对 RxTask 进行迭代升级有兴趣的同学可以了解下 RxTask 的设计及实现理念

作用域的设想及机制

熟悉 RxTask 的同学们都知道在原有的 RxTask 设计理念并没有存在 ITaskScope 这一概念,这一概念可以理解为限制当前创建的 RxTask 存活在某一对象中,当该对象被销毁时通过 ITaskScope 实例接口及时告知 RxTask 进行销毁操作。避免 RxTask 还在运行,譬如在 Android 环境中 Activity 运行一个异步 RxTask 由于Activity 在某些场景被销毁时,RxTask 来不及销毁仍然继续执行最终执行完成时回到 Activity 操作相关 UI 此时,则会报出异常从而导致崩溃或 RxTask 持续运行中不断消耗资源导致内存一直抖动,当然这都是因为开发者没有及时的控制好RxTask 出现的问题。为此提出 ITaskScope 概念,通过实现 ITaskScope 将 RxTask 与某个对象生命作用域进行关联从而及时进行销毁避免出现上诉问题。

接下来请看机制时序图:

从机制图中可以得到当 scope 处于销毁动作时则会告知 Task 对象让其取消执行,最后释放资源。

ITaskScope 的实现

那么 ITaskScope 接口定义如下

interface ITaskScope {
    fun scopeOnDestroy()
    fun subScope(callAction: ITaskScopeCallAction?)
}
interface ITaskScopeCallAction {
    fun doOnScopeDestroyAction()
}

为什么在 ITaskScope 接口中会多出一个 ITaskScopeCallAction 接口呢?

其实同学可以这样理解 ITaskScope 仅仅负责在某个对象中持有单个或多 RxTask 对象,该对象处于销毁时期时及时调用 ITaskScope.scopeOnDestory() 方法去告知被持有 RxTask 对象们及时销毁,此刻为了避免 ITaskScope 对象会直接操作或联系 RxTask 对象那么,通过 ITaskScopeCallAction 去进行告知相关 RxTask 进行相应操作。

那么 ITaskScopeCallAction 仅仅负责处理销毁操作回调事件即可。

同学们还记得 RxTask 奠基石接口 ITask 吗?没错既然我们把 ITaskScopeITaskScopeCallAction 声明了那么,我们则需要利用 ITask 接口声明ITaskScope 绑定关系。

interface ITask<RESULT> {
    //启动
    fun start()
    //取消
    fun cancel()
    fun bindScope(scope: ITaskScope?): ITask<RESULT>?
}

接下来再 RxTask 核心基类中实现关联关系即可:

abstract class ISuperTask<RESULT> : ITask<RESULT> {
    protected var taskScope: ITaskScope? = null
    protected var iTaskScopeCallAction: ITaskScopeCallAction = object : ITaskScopeCallAction {
        override fun doOnScopeDestroyAction() {
            cancel()
        }
    }
    override fun bindScope(scope: ITaskScope?): ITask<RESULT>? {
        scope?.subScope(iTaskScopeCallAction)
        return this
    }
}

基于 Android 平台拓展支持

熟悉 RxTask 库的同学们,都会清晰知道 RxTask 分为 libRxTasklibRxTaskAndroidExpand :

libRxTask 作为 RxTask 基准及核心实现并支持后端直接使用。

libRxTaskAndroidExpand 作为对 Android 平台进行拓展简单延伸的封装。

那么在 libRxTaskAndroidExpand 库中我们可以结合 Lifecycle 实现一个简单封装的 Scope 对象给同学们使用。

详细实现如下:

class RxTaskAndroidBasePageScope : ITaskScope, LifecycleEventObserver {
    var canelByStopStatus = false
    var cancelByPauseStatus = false
    var cancelByDestroyStatus = true
    private var observers: MutableList<ITaskScopeCallAction> = mutableListOf()
    override fun scopeOnDestroy() {
        observers.forEach { it?.doOnScopeDestroyAction() }
    }
    override fun subScope(callAction: ITaskScopeCallAction?) {
        callAction?.let {
            if (!observers.contains(it))
                observers.add(it)
        }
    }
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        when (event) {
            Lifecycle.Event.ON_PAUSE -> {
                if (cancelByPauseStatus) {
                    scopeOnDestroy()
                    return
                }
            }
            Lifecycle.Event.ON_STOP -> {
                if (canelByStopStatus) {
                    scopeOnDestroy()
                    return
                }
            }
            Lifecycle.Event.ON_DESTROY -> {
                if (cancelByDestroyStatus) {
                    scopeOnDestroy()
                    return
                }
            }
            else -> {
            }
        }
    }
}

那么使用如下(以 android 平台为例子):

class MainActivity : AppCompatActivity() {
    val scope = RxTaskAndroidBasePageScope()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycle.addObserver(scope)
        RxTaskAndroidDefaultInit.instant.defaultInit()
//
        val task = object : SingleEvaluation<*> {
            override fun evluation(task: RxSingleEvaluationTask<*>): Object {
                //do your logic
                return JsonObject()
            }
        }.getTask()
        .bindScope(scope)
        .start()
    }
}

总结

写出一个库其实不难,难点在于如何理解通用性、简易性、拓展性、维护性,更重要的是需要虚心接受各方建议及反馈并进行修改,持续更新改进

以上就是协程作用域概念迭代RxTask 实现自主控制的详细内容,更多关于RxTask 自主控制的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

协程作用域概念迭代RxTask 实现自主控制

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

协程作用域概念迭代RxTask 实现自主控制

这篇文章主要为大家介绍了协程作用域概念迭代RxTask实现自主控制详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录