協(xié)程作用域概念迭代RxTask?實(shí)現(xiàn)自主控制
結(jié)合協(xié)程作用域概念迭代 RxTask 實(shí)現(xiàn)作用域功能
在過去的一段時(shí)間里有幸接觸過某個(gè)項(xiàng)目,整體技術(shù)方案落后且線程濫用導(dǎo)致出現(xiàn)大量的內(nèi)存泄漏或者資源反復(fù)耗費(fèi)。原因在于這個(gè)項(xiàng)目中對(duì) RxJava 創(chuàng)建操作不規(guī)范,反復(fù)創(chuàng)建線程且不及時(shí)消耗導(dǎo)致,剛好朋友在使用我的 RxTask 開源項(xiàng)目中也給我反饋一件事,能否提供一個(gè)類似像協(xié)程作用域概念,當(dāng)被告知需要消耗時(shí)則及時(shí)把 RxTask 銷毀。故此針對(duì) RxTask 進(jìn)行迭代升級(jí)有興趣的同學(xué)可以了解下 RxTask 的設(shè)計(jì)及實(shí)現(xiàn)理念
作用域的設(shè)想及機(jī)制
熟悉 RxTask 的同學(xué)們都知道在原有的 RxTask 設(shè)計(jì)理念并沒有存在 ITaskScope 這一概念,這一概念可以理解為限制當(dāng)前創(chuàng)建的 RxTask 存活在某一對(duì)象中,當(dāng)該對(duì)象被銷毀時(shí)通過 ITaskScope 實(shí)例接口及時(shí)告知 RxTask 進(jìn)行銷毀操作。避免 RxTask 還在運(yùn)行,譬如在 Android 環(huán)境中 Activity 運(yùn)行一個(gè)異步 RxTask 由于Activity 在某些場(chǎng)景被銷毀時(shí),RxTask 來不及銷毀仍然繼續(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)殚_發(fā)者沒有及時(shí)的控制好RxTask 出現(xiàn)的問題。為此提出 ITaskScope 概念,通過實(shí)現(xiàn) ITaskScope 將 RxTask 與某個(gè)對(duì)象生命作用域進(jìn)行關(guān)聯(lián)從而及時(shí)進(jìn)行銷毀避免出現(xiàn)上訴問題。
接下來請(qǐng)看機(jī)制時(shí)序圖:
從機(jī)制圖中可以得到當(dāng) scope 處于銷毀動(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ì)象處于銷毀時(shí)期時(shí)及時(shí)調(diào)用 ITaskScope.scopeOnDestory()
方法去告知被持有 RxTask
對(duì)象們及時(shí)銷毀,此刻為了避免 ITaskScope
對(duì)象會(huì)直接操作或聯(lián)系 RxTask
對(duì)象那么,通過 ITaskScopeCallAction
去進(jìn)行告知相關(guān) RxTask
進(jìn)行相應(yīng)操作。
那么 ITaskScopeCallAction
僅僅負(fù)責(zé)處理銷毀操作回調(diào)事件即可。
同學(xué)們還記得 RxTask
奠基石接口 ITask
嗎?沒錯(cuò)既然我們把 ITaskScope
、ITaskScopeCallAction
聲明了那么,我們則需要利用 ITask
接口聲明ITaskScope
綁定關(guān)系。
interface ITask<RESULT> { //啟動(dòng) fun start() //取消 fun cancel() fun bindScope(scope: ITaskScope?): ITask<RESULT>? }
接下來再 RxTask 核心基類中實(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
庫的同學(xué)們,都會(huì)清晰知道 RxTask
分為 libRxTask
及 libRxTaskAndroidExpand
:
libRxTask
作為 RxTask
基準(zhǔn)及核心實(shí)現(xiàn)并支持后端直接使用。
libRxTaskAndroidExpand
作為對(duì) Android
平臺(tái)進(jìn)行拓展簡(jiǎn)單延伸的封裝。
那么在 libRxTaskAndroidExpand
庫中我們可以結(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é)
寫出一個(gè)庫其實(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-05Android填坑系列:在小米系列等機(jī)型上放開定位權(quán)限后的定位請(qǐng)求彈框示例
本文詳細(xì)介紹了在小米系列等機(jī)型上放開定位權(quán)限后的定位請(qǐng)求彈框示例,例如在應(yīng)用軟件中提示顯示定位服務(wù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-11-11Flutter打包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-08Android自定義View實(shí)現(xiàn)九宮格圖形解鎖(Kotlin版)
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)九宮格圖形解鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09android socket聊天室功能實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了android socket聊天室功能實(shí)現(xiàn)方法,不單純是聊天室,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Android Coil對(duì)比Glide深入分析探究
這篇文章主要介紹了Android Coil對(duì)比Glide,Coil是Android上的一個(gè)全新的圖片加載框架,它的全名叫做coroutine image loader,即協(xié)程圖片加載庫2023-02-02基于VSTS的Xamarin.Android持續(xù)集成步驟詳解
這篇文章主要介紹了基于VSTS的Xamarin.Android持續(xù)集成步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04Android 如何獲取設(shè)備唯一標(biāo)識(shí)
這篇文章主要介紹了Android 如何獲取設(shè)備唯一標(biāo)識(shí),幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03