协程作用域概念迭代RxTask 实现自主控制
作者:king@killer
结合协程作用域概念迭代 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
吗?没错既然我们把 ITaskScope
、ITaskScopeCallAction
声明了那么,我们则需要利用 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
分为 libRxTask
及 libRxTaskAndroidExpand
:
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 自主控制的资料请关注脚本之家其它相关文章!