協(xié)程作用域概念迭代RxTask?實(shí)現(xiàn)自主控制
結(jié)合協(xié)程作用域概念迭代 RxTask 實(shí)現(xiàn)作用域功能
在過(guò)去的一段時(shí)間里有幸接觸過(guò)某個(gè)項(xiàng)目,整體技術(shù)方案落后且線(xiàn)程濫用導(dǎo)致出現(xiàn)大量的內(nèi)存泄漏或者資源反復(fù)耗費(fèi)。原因在于這個(gè)項(xiàng)目中對(duì) RxJava 創(chuàng)建操作不規(guī)范,反復(fù)創(chuàng)建線(xiàn)程且不及時(shí)消耗導(dǎo)致,剛好朋友在使用我的 RxTask 開(kāi)源項(xiàng)目中也給我反饋一件事,能否提供一個(gè)類(lèi)似像協(xié)程作用域概念,當(dāng)被告知需要消耗時(shí)則及時(shí)把 RxTask 銷(xiāo)毀。故此針對(duì) RxTask 進(jìn)行迭代升級(jí)有興趣的同學(xué)可以了解下 RxTask 的設(shè)計(jì)及實(shí)現(xiàn)理念
作用域的設(shè)想及機(jī)制

熟悉 RxTask 的同學(xué)們都知道在原有的 RxTask 設(shè)計(jì)理念并沒(méi)有存在 ITaskScope 這一概念,這一概念可以理解為限制當(dāng)前創(chuàng)建的 RxTask 存活在某一對(duì)象中,當(dāng)該對(duì)象被銷(xiāo)毀時(shí)通過(guò) ITaskScope 實(shí)例接口及時(shí)告知 RxTask 進(jìn)行銷(xiāo)毀操作。避免 RxTask 還在運(yùn)行,譬如在 Android 環(huán)境中 Activity 運(yùn)行一個(gè)異步 RxTask 由于Activity 在某些場(chǎng)景被銷(xiāo)毀時(shí),RxTask 來(lái)不及銷(xiāo)毀仍然繼續(xù)執(zhí)行最終執(zhí)行完成時(shí)回到 Activity 操作相關(guān) UI 此時(shí),則會(huì)報(bào)出異常從而導(dǎo)致崩潰或 RxTask 持續(xù)運(yùn)行中不斷消耗資源導(dǎo)致內(nèi)存一直抖動(dòng),當(dāng)然這都是因?yàn)殚_(kāi)發(fā)者沒(méi)有及時(shí)的控制好RxTask 出現(xiàn)的問(wèn)題。為此提出 ITaskScope 概念,通過(guò)實(shí)現(xiàn) ITaskScope 將 RxTask 與某個(gè)對(duì)象生命作用域進(jìn)行關(guān)聯(lián)從而及時(shí)進(jìn)行銷(xiāo)毀避免出現(xiàn)上訴問(wèn)題。
接下來(lái)請(qǐng)看機(jī)制時(shí)序圖:

從機(jī)制圖中可以得到當(dāng) scope 處于銷(xiāo)毀動(dòng)作時(shí)則會(huì)告知 Task 對(duì)象讓其取消執(zhí)行,最后釋放資源。
ITaskScope 的實(shí)現(xiàn)
那么 ITaskScope 接口定義如下
interface ITaskScope {
fun scopeOnDestroy()
fun subScope(callAction: ITaskScopeCallAction?)
}
interface ITaskScopeCallAction {
fun doOnScopeDestroyAction()
}
為什么在 ITaskScope 接口中會(huì)多出一個(gè) ITaskScopeCallAction 接口呢?
其實(shí)同學(xué)可以這樣理解 ITaskScope 僅僅負(fù)責(zé)在某個(gè)對(duì)象中持有單個(gè)或多 RxTask 對(duì)象,該對(duì)象處于銷(xiāo)毀時(shí)期時(shí)及時(shí)調(diào)用 ITaskScope.scopeOnDestory() 方法去告知被持有 RxTask 對(duì)象們及時(shí)銷(xiāo)毀,此刻為了避免 ITaskScope 對(duì)象會(huì)直接操作或聯(lián)系 RxTask 對(duì)象那么,通過(guò) ITaskScopeCallAction 去進(jìn)行告知相關(guān) RxTask 進(jìn)行相應(yīng)操作。
那么 ITaskScopeCallAction 僅僅負(fù)責(zé)處理銷(xiāo)毀操作回調(diào)事件即可。
同學(xué)們還記得 RxTask 奠基石接口 ITask 嗎?沒(méi)錯(cuò)既然我們把 ITaskScope 、ITaskScopeCallAction 聲明了那么,我們則需要利用 ITask 接口聲明ITaskScope 綁定關(guān)系。
interface ITask<RESULT> {
//啟動(dòng)
fun start()
//取消
fun cancel()
fun bindScope(scope: ITaskScope?): ITask<RESULT>?
}
接下來(lái)再 RxTask 核心基類(lèi)中實(shí)現(xiàn)關(guān)聯(lián)關(guān)系即可:
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 平臺(tái)拓展支持
熟悉 RxTask 庫(kù)的同學(xué)們,都會(huì)清晰知道 RxTask 分為 libRxTask 及 libRxTaskAndroidExpand :
libRxTask 作為 RxTask 基準(zhǔn)及核心實(shí)現(xiàn)并支持后端直接使用。
libRxTaskAndroidExpand 作為對(duì) Android 平臺(tái)進(jìn)行拓展簡(jiǎn)單延伸的封裝。
那么在 libRxTaskAndroidExpand 庫(kù)中我們可以結(jié)合 Lifecycle 實(shí)現(xiàn)一個(gè)簡(jiǎn)單封裝的 Scope 對(duì)象給同學(xué)們使用。
詳細(xì)實(shí)現(xiàn)如下:
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 平臺(tái)為例子):
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()
}
}
總結(jié)
寫(xiě)出一個(gè)庫(kù)其實(shí)不難,難點(diǎn)在于如何理解通用性、簡(jiǎn)易性、拓展性、維護(hù)性,更重要的是需要虛心接受各方建議及反饋并進(jìn)行修改,持續(xù)更新改進(jìn)
以上就是協(xié)程作用域概念迭代RxTask 實(shí)現(xiàn)自主控制的詳細(xì)內(nèi)容,更多關(guān)于RxTask 自主控制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android應(yīng)用程序的編譯流程及使用Ant編譯項(xiàng)目的攻略
這篇文章主要介紹了Android應(yīng)用程序的編譯流程及使用Ant編譯項(xiàng)目的攻略,Ant是集編譯測(cè)試部署于一體的Java自動(dòng)化工具,要的朋友可以參考下2016-04-04
解析Android中使用自定義字體的實(shí)現(xiàn)方法
本篇文章是對(duì)在Android中使用自定義字體的方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05
Android填坑系列:在小米系列等機(jī)型上放開(kāi)定位權(quán)限后的定位請(qǐng)求彈框示例
本文詳細(xì)介紹了在小米系列等機(jī)型上放開(kāi)定位權(quán)限后的定位請(qǐng)求彈框示例,例如在應(yīng)用軟件中提示顯示定位服務(wù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-11-11
Flutter打包apk報(bào)錯(cuò)Your?app?isn't?using?AndroidX解決
這篇文章主要為大家介紹了Flutter打包apk報(bào)錯(cuò)Your?app?isn't?using?AndroidX解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
Android自定義View實(shí)現(xiàn)九宮格圖形解鎖(Kotlin版)
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)九宮格圖形解鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
android socket聊天室功能實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了android socket聊天室功能實(shí)現(xiàn)方法,不單純是聊天室,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Android Coil對(duì)比Glide深入分析探究
這篇文章主要介紹了Android Coil對(duì)比Glide,Coil是Android上的一個(gè)全新的圖片加載框架,它的全名叫做coroutine image loader,即協(xié)程圖片加載庫(kù)2023-02-02
基于VSTS的Xamarin.Android持續(xù)集成步驟詳解
這篇文章主要介紹了基于VSTS的Xamarin.Android持續(xù)集成步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
Android 如何獲取設(shè)備唯一標(biāo)識(shí)
這篇文章主要介紹了Android 如何獲取設(shè)備唯一標(biāo)識(shí),幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03

