开发者

Android协程高级用法大全

目录
  • 1️⃣ 协程作用域(CoroutineScope)与生命周期绑定
    • Activity/Fragment 中
    • 手动创建 CoroutineScope
  • 2️⃣ 编程异步组合:并发和串行
    • 串行执行
    • 并行执行
    • 并行 + awaitAll
  • 3️⃣ 异常处理与结构化并发
    • try-catch
    • CoroutineExceptionHandler
    • SupervisorJob
  • 4️⃣ 切换线程/调度器
    • usewithContext替代launch切换线程
  • 5️⃣ 超时与取消
    • 超时
    • 取消
    • 可取消挂起函数
  • 6️⃣ Channels 与 Flow(响应式数据流)
    • Channel
    • Flow
  • 7️⃣ 高级技巧

    这里系统梳理一下 android/Kotlin 协程 的一些高级用法。会从 上下文管理、作用域控制、异常处理、性能优化、异步组合 等角度讲解,给你落地可用的示例。

    1️⃣ 协程作用域(CoroutineScope)与生命周期绑定

    在 Android 中,协程最好绑定到 生命周期,避免内存泄漏。

    Activity/FragmentKePxX

    class MainActivity : AppCompatActivity() {
        // 生命周期感知协程作用域
        private val scope = lifejavascriptcycleScope
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            scope.launch {
                val data = fetchData()
                updateUI(data)
            }
        }
    }
    • lifecycleScope:绑定 Activity/Fragment 生命周期,自动取消
    • viewModelScope:绑定 ViewModel 生命周期

    手动创建 CoroutineScope

    private val customScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    • 可以用 SupervisorJob() 避免一个子协程失败影响其它子协程
    • 记得在 onDestroy() 或 onCleared() 时 customScope.cancel()

    2️⃣ 异步组合:并发和串行

    串行执行

    val result1 = async { fejavascripttchData1() }.await()
    val result2 = async { fetchData2() }.await()
    val finalResult = combine(result1, result2)
    • 按顺序等待,每个任务完成后再执行下一个

    并行执行

    val deferred1 = async { fetchData1() }
    val deferred2 = async { fetchData2() }
    val result1 = deferred1.await()
    val result2 = deferred2.await()
    • 并行启http://www.devze.com动,节省等待时间

    并行 + awaitAll

    val results = awaitAll(
        async { fetchData1() },
        async { fetchData2() },
        async { fetchData3() }
    )

    3️⃣ 异常处理与结构化并发

    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

    • 父协程失败不影响子协程
    val supervisor = SupervisorJob()
    val scope = CoroutineScope(Dispatchers.IO + supervisor)

    4️⃣ 切换线程/调度器

    • Dispatchers.Main → UI 操作
    • Dispatchers.IO → 网络/文件操作
    • 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() // 立即取消

    可取消挂起函数

    • 网络、延迟、Channel 等挂起函数是可取消的
    • CPU 密集型循环需要手动检查 isActive
    for (i in 1..1000) {
        if (!isActive) break
        doWork()
    }

    6️⃣ Channels 与 Flow(响应式数据流)

    Channel

    • 类似队列,生产者和消费者解耦
    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() // 真正开始执行
    • 异常隔离
      • 使用 SupervisorJob() 避免一个子协程挂掉影响整个父协程

    到此这篇关于Android协程的用法大全的文章就介绍到这了,更多相关Android协程用法内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜