Android協(xié)程高級用法大全
這里系統(tǒng)梳理一下 Android/Kotlin 協(xié)程 的一些高級用法。會從 上下文管理、作用域控制、異常處理、性能優(yōu)化、異步組合 等角度講解,給你落地可用的示例。
1?? 協(xié)程作用域(CoroutineScope)與生命周期綁定
在 Android 中,協(xié)程最好綁定到 生命周期,避免內(nèi)存泄漏。
Activity/Fragment 中
class MainActivity : AppCompatActivity() {
// 生命周期感知協(xié)程作用域
private val scope = lifecycleScope
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
scope.launch {
val data = fetchData()
updateUI(data)
}
}
}- lifecycleScope:綁定 Activity/Fragment 生命周期,自動取消
- viewModelScope:綁定 ViewModel 生命周期
手動創(chuàng)建 CoroutineScope
private val customScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
- 可以用
SupervisorJob()避免一個子協(xié)程失敗影響其它子協(xié)程 - 記得在
onDestroy()或onCleared()時customScope.cancel()
2?? 異步組合:并發(fā)和串行
串行執(zhí)行
val result1 = async { fetchData1() }.await()
val result2 = async { fetchData2() }.await()
val finalResult = combine(result1, result2)- 按順序等待,每個任務(wù)完成后再執(zhí)行下一個
并行執(zhí)行
val deferred1 = async { fetchData1() }
val deferred2 = async { fetchData2() }
val result1 = deferred1.await()
val result2 = deferred2.await()- 并行啟動,節(jié)省等待時間
并行 + awaitAll
val results = awaitAll(
async { fetchData1() },
async { fetchData2() },
async { fetchData3() }
)3?? 異常處理與結(jié)構(gòu)化并發(fā)
try-catch
scope.launch {
try {
val result = fetchData()
} catch (e: IOException) {
handleError(e)
}
}CoroutineExceptionHandler
val handler = CoroutineExceptionHandler { _, exception ->
Log.e("Coroutine", "Caught $exception")
}
scope.launch(handler) {
val result = fetchData()
}SupervisorJob
- 父協(xié)程失敗不影響子協(xié)程
val supervisor = SupervisorJob() val scope = CoroutineScope(Dispatchers.IO + supervisor)
4?? 切換線程/調(diào)度器
- Dispatchers.Main → UI 操作
- Dispatchers.IO → 網(wǎng)絡(luò)/文件操作
- Dispatchers.Default → CPU 密集型計算
scope.launch(Dispatchers.IO) {
val data = fetchData()
withContext(Dispatchers.Main) {
updateUI(data)
}
}usewithContext替代launch切換線程
- 便于返回值,避免嵌套
launch
5?? 超時與取消
超時
try {
withTimeout(3000L) {
fetchData()
}
} catch (e: TimeoutCancellationException) {
Log.e("Coroutine", "Timeout")
}取消
val job = scope.launch {
fetchData()
}
job.cancel() // 立即取消可取消掛起函數(shù)
- 網(wǎng)絡(luò)、延遲、Channel 等掛起函數(shù)是可取消的
- CPU 密集型循環(huán)需要手動檢查
isActive:
for (i in 1..1000) {
if (!isActive) break
doWork()
}6?? Channels 與 Flow(響應(yīng)式數(shù)據(jù)流)
Channel
- 類似隊列,生產(chǎn)者和消費(fèi)者解耦
val channel = Channel<Int>()
scope.launch {
for (i in 1..5) channel.send(i)
channel.close()
}
scope.launch {
for (i in channel) {
println(i)
}
}Flow
- Kotlin 原生的冷流,支持各種操作符
fun fetchNumbers(): Flow<Int> = flow {
for (i in 1..5) {
delay(100)
emit(i)
}
}
scope.launch {
fetchNumbers()
.map { it * 2 }
.filter { it > 5 }
.collect { println(it) }
}7?? 高級技巧
- 組合多個異步源
val flow1 = flow { emit(fetchData1()) }
val flow2 = flow { emit(fetchData2()) }
flow1.combine(flow2) { d1, d2 -> d1 + d2 }
.collect { println(it) }- 懶啟動的 async
val deferred = async(start = CoroutineStart.LAZY) { fetchData() }
deferred.await() // 真正開始執(zhí)行- 異常隔離
- 使用
SupervisorJob()避免一個子協(xié)程掛掉影響整個父協(xié)程
- 使用
到此這篇關(guān)于Android協(xié)程的用法大全的文章就介紹到這了,更多相關(guān)Android協(xié)程用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android?Flutter繪制有趣的?loading加載動畫
在網(wǎng)絡(luò)速度較慢的場景,一個有趣的加載會提高用戶的耐心和對?App?的好感。本篇我們利用Flutter?的?PathMetric來玩幾個有趣的?loading?效果,感興趣的可以動手嘗試一下2022-07-07
Android ViewPager實現(xiàn)無限循環(huán)的實例
這篇文章主要介紹了Android ViewPager實現(xiàn)無限循環(huán)的實例的相關(guān)資料,需要的朋友可以參考下2017-07-07
Android LuBan與Compressor圖片壓縮方式
本篇文章主要介紹了Android LuBan與Compressor圖片壓縮方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04
Android NDK開發(fā)的環(huán)境搭建與簡單示例
本文主要介紹Android NDK的知識,這里整理了相關(guān)資料,來說明如何搭建相應(yīng)環(huán)境和簡單實例,幫助大家理解,有興趣的小伙伴可以參考下2016-09-09

