当前位置: 代码网 > it编程>App开发>Android > Android协程高级用法大全

Android协程高级用法大全

2025年08月19日 Android 我要评论
这里系统梳理一下android/kotlin 协程的一些高级用法。会从上下文管理、作用域控制、异常处理、性能优化、异步组合等角度讲解,给你落地可用的示例。1️⃣ 协程作用域(coroutinescop

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

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

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

activity/fragment 中

class mainactivity : appcompatactivity() {
    // 生命周期感知协程作用域
    private val scope = lifecyclescope
    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 { fetchdata1() }.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()
  • 并行启动,节省等待时间

并行 + 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协程用法内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com