Android 开发中如何使用Coroutines

Android 平台下 Kotlin 协程(coroutines)的使用 ,结合 Android 组件生命周期(Activity/Fragment/ViewModel)、官方最佳实践,从基础依赖、核心概念、组件化用法、实战场景、避坑要点全维度讲解,同时适配 Retrofit 网络框架,替代 RxJava 实现更简洁的异步操作。

协程是 Android 官方唯一推荐 的异步编程方案,相比 Thread/Handler/RxJava,核心优势是语法简洁、非阻塞挂起、自动生命周期绑定(解决内存泄漏)、原生支持 Android 组件 ,下面的内容兼顾基础理解生产实战,新手也能快速上手。

一、前置准备:依赖配置与基础要求

1. 核心依赖(必须)

Android 中使用协程需要两个核心依赖,版本必须完全一致 ,同时搭配 Android 官方的lifecycle-ktx(提供组件内置协程作用域,无需手动创建)。截至 2026.02,协程最新稳定版为 1.8.0 ,适配 Kotlin 1.9.0+(Android Studio 新建项目默认适配),配置在模块级build.gradle/build.gradle.kts

gradle

复制代码
// Kotlin协程核心(跨平台基础,必选)
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0'
// Kotlin协程Android扩展(Android专属适配,必选)
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0'

// Android生命周期扩展(提供Activity/Fragment/ViewModel内置协程作用域,必选)
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0'
  • 若用Kotlin DSL(build.gradle.kts) ,依赖格式为:

    kotlin

    复制代码
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0")
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
2. 基础要求(默认满足)
  • Kotlin 版本:1.6.0+(Android Studio 2021.1 + 新建项目默认满足);

  • Android Gradle Plugin:7.0.0+

  • 开启 Java 8 兼容(新建项目默认开启,若未开启需手动配置): gradle

    复制代码
    android {
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
        // 若用Kotlin,需加这行
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }

二、核心概念:3 个必懂知识点(理解后再用)

协程的核心用法围绕 **「作用域、调度器、挂起函数」展开,这 3 个概念是 Android 协程的基础,比 API 更重要,且所有 API 均基于这 3 个概念 **。

1. 协程作用域(CoroutineScope):协程的生命周期管理者
  • 核心意义所有协程必须在作用域中启动 ,作用域是协程的 "容器",作用域销毁时,其下所有协程会被自动取消 ,从根本上解决 Android 异步操作的内存泄漏问题(这是协程对比 Thread/RxJava 的核心优势)。
  • Android 专属福利 :无需手动创建CoroutineScope,官方为所有核心 Android 组件 提供了内置作用域 (与组件生命周期自动绑定),直接使用即可,这是 Android 协程的标准用法
  • 内置作用域分类 (后续重点讲解):
    • viewModelScope:ViewModel 的内置作用域,销毁时机为ViewModel.onCleared()
    • lifecycleScope:Activity/Fragment 的内置作用域,销毁时机为onDestroy()
2. 调度器(Dispatchers):指定协程的执行线程
  • 核心意义 :调度器用于指定协程在哪个线程执行,通过调度器可轻松实现 **「子线程执行耗时操作,主线程更新 UI」** 的 Android 经典场景。

  • 4 个核心调度器 (前 3 个来自core库,第 4 个来自android库,Android 开发仅用这 4 个):

    调度器 核心作用 适用场景
    Dispatchers.Main Android主线程(UI 线程) 更新 UI、调用主线程 API(Toast/View 操作 / Activity 跳转)
    Dispatchers.IO IO 密集型线程池(子线程) 网络请求、数据库操作、文件读写、SP 存储(Android 最常用
    Dispatchers.Default 计算密集型线程池(子线程) 数据解析、列表排序、复杂计算(CPU 密集型操作)
    Dispatchers.Unconfined 无指定线程 几乎不使用(易导致线程混乱,仅特殊场景用)
  • Android 关键特性viewModelScope/lifecycleScope默认调度器是Dispatchers.Main(主线程),因此协程启动后默认在主线程执行,无需手动指定。

3. 挂起函数(suspend 关键字):非阻塞的耗时操作
  • 核心意义 :用suspend修饰的函数为挂起函数 ,是协程的核心特性,具备两个关键能力:
    1. 可暂停执行 :在协程中调用挂起函数时,协程会暂停执行 (如等待网络请求 / 数据库查询结果),暂停时不会阻塞线程(线程可继续执行其他协程);
    2. 自动恢复执行 :挂起函数执行完成(如网络请求拿到结果)后,协程会自动恢复执行,继续执行后续代码。
  • 核心规则挂起函数仅能在协程中或其他挂起函数中调用,普通函数无法直接调用(这是语法约束,编译器会强制检查)。
  • Android 实战 :Retrofit3/ROOM/Glide 等主流库均已对协程做了原生支持 ,提供了现成的挂起函数,无需自己实现(如 Retrofit3 的接口只需加suspend关键字即可成为挂起函数)。

三、Android 协程的标准用法:3 个内置作用域实战

Android 协程的最佳实践直接使用官方内置作用域 ,无需手动创建CoroutineScope,无需手动管理协程生命周期,无需手动取消协程,一行代码启动协程,生命周期自动绑定 。下面按 **「MVVM 开发优先级」讲解 3 个内置作用域的用法, viewModelScope是 MVVM 开发的首选 **(生命周期最长,不受 Activity 重建影响)。

1. viewModelScope:ViewModel 的内置作用域(MVVM 首选)
  • 核心特性

    1. ViewModel的生命周期严格绑定ViewModel销毁时(onCleared()),作用域下所有协程自动取消
    2. 不受 Activity/Fragment 重建影响 (如屏幕旋转 / 切后台导致的 Activity 重建),协程会继续执行,这是viewModelScope对比lifecycleScope核心优势
    3. 默认调度器为Dispatchers.Main(主线程),无需手动指定;
  • 适用场景MVVM 架构中所有异步操作 (网络请求、数据库操作、文件读写),这是 Android 开发的标准用法(将所有业务逻辑放在 ViewModel 中)。

  • 实战用法 :直接在 ViewModel 中调用viewModelScope.launch { ... }即可启动协程,结合withContext切换线程。

    kotlin

    复制代码
    import androidx.lifecycle.ViewModel
    import androidx.lifecycle.viewModelScope // 导入viewModelScope
    import kotlinx.coroutines.Dispatchers
    import kotlinx.coroutines.launch
    import kotlinx.coroutines.withContext
    
    // 普通ViewModel,无需继承任何额外类,直接用viewModelScope
    class UserViewModel : ViewModel() {
        // 登录方法:供View层(Activity/Fragment)调用
        fun login(username: String, password: String) {
            // 1. 启动协程:直接用viewModelScope.launch,默认在主线程执行
            viewModelScope.launch {
                try {
                    // 2. 切换到IO线程执行耗时操作(网络请求):withContext(Dispatchers.IO)
                    // withContext是挂起函数,会暂停协程,执行完成后自动恢复
                    val loginResult = withContext(Dispatchers.IO) {
                        // 此处执行耗时操作:如Retrofit3网络请求(后续实战讲解)
                        // 模拟网络请求:延迟2秒,返回登录结果
                        Thread.sleep(2000) // 实际开发用真实挂起函数,禁止用Thread.sleep
                        "登录成功,用户名:$username"
                    }
    
                    // 3. 自动切回主线程(viewModelScope默认Main),处理结果(如更新数据)
                    // 此处可更新LiveData/StateFlow,供View层观察更新UI
                    println("登录结果:$loginResult")
                } catch (e: Exception) {
                    // 4. 统一处理异常(网络异常/业务异常等)
                    println("登录失败:${e.message}")
                }
            }
        }
    }
  • View 层(Activity)调用 :直接调用 ViewModel 方法即可,无需关注协程:

    kotlin

    复制代码
    class LoginActivity : AppCompatActivity() {
        // 初始化ViewModel
        private val userViewModel by viewModels<UserViewModel>()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_login)
    
            // 点击登录按钮,直接调用ViewModel方法
            btnLogin.setOnClickListener {
                val username = etUsername.text.toString().trim()
                val password = etPassword.text.toString().trim()
                userViewModel.login(username, password)
            }
        }
    }
2. lifecycleScope:Activity/Fragment 的内置作用域
  • 核心特性

    1. 与 Activity/Fragment 的生命周期严格绑定 ,组件销毁时(onDestroy()),协程自动取消;
    2. 受 Activity/Fragment 重建影响(如屏幕旋转),重建后协程会被取消并重新执行;
    3. 默认调度器为Dispatchers.Main(主线程);
  • 适用场景仅与页面生命周期相关的异步操作 (如页面可见时刷新 UI、页面销毁前保存临时数据),不建议用于网络请求 / 数据库操作(易因页面重建导致请求中断)。

  • 实战用法 :直接在 Activity/Fragment 中调用lifecycleScope.launch { ... }

    kotlin

    复制代码
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            // 启动协程:lifecycleScope
            lifecycleScope.launch {
                // 切换到IO线程执行耗时操作
                val data = withContext(Dispatchers.IO) {
                    // 模拟文件读写
                    Thread.sleep(1000)
                    "从文件中读取的内容"
                }
                // 切回主线程更新UI
                tvData.text = data
                Toast.makeText(this@MainActivity, data, Toast.LENGTH_SHORT).show()
            }
        }
    }
3. 生命周期感知的协程启动(launchWhenXxx

lifecycleScope提供了 3 个生命周期感知 的扩展方法,让协程仅在指定的生命周期状态执行 ,状态不满足时暂停执行 ,状态恢复时继续执行 ,适合依赖页面可见性的异步操作(如页面可见时才请求数据)。

kotlin

复制代码
lifecycleScope.launchWhenResumed {
    // 仅当页面处于「Resumed」状态(可见、可交互)时执行
    // 页面进入Pause状态时,协程暂停;回到Resumed状态时,协程继续执行
    val data = withContext(Dispatchers.IO) { api.getData() }
    tvData.text = data
}

// 其他两个方法
lifecycleScope.launchWhenCreated { /* 仅Created状态执行 */ }
lifecycleScope.launchWhenStarted { /* 仅Started/Resumed状态执行 */ }

四、核心 API:Android 开发仅用这 5 个(简洁高效)

Android 协程的 API 非常简洁,生产开发中仅需掌握 5 个核心 API,即可覆盖 99% 的场景,所有 API 均基于上述 3 个核心概念,无需记忆复杂 API。

1. launch:启动无返回值的协程(最常用)
  • 作用 :启动无返回值的协程,适合执行 "只做不返回" 的操作(如网络请求后更新 UI、文件读写、数据库操作);
  • 用法scope.launch { 协程执行体 }scope为内置作用域(viewModelScope/lifecycleScope);
  • 核心特性 :默认在作用域的默认调度器执行(Main 线程),通过withContext切换线程。
2. withContext:切换协程的调度器(核心中的核心)
  • 作用在协程内部切换执行线程 ,执行完成后自动切回原线程 ,是 Android 中 **「子线程执行耗时操作,主线程更新 UI」唯一方式 **;

  • 性质挂起函数,会暂停协程,执行完成后恢复;

  • 用法withContext(调度器) { 耗时操作 },返回值为耗时操作的结果;

  • 实战示例 (Android 最经典场景):

    kotlin

    复制代码
    viewModelScope.launch {
        // 主线程(默认)
        val result = withContext(Dispatchers.IO) {
            // IO子线程:执行网络请求/文件读写
            api.login(username, password) // 挂起函数
        }
        // 自动切回主线程:更新UI/处理结果
        _userLiveData.value = result
    }
3. suspend:定义挂起函数(对接第三方库)
  • 作用 :修饰函数为挂起函数,让函数具备 "暂停 / 恢复" 能力,可在协程中调用;
  • Android 实战无需自己实现挂起函数 ,主流第三方库均已提供现成的挂起函数:
    • Retrofit3:接口方法加suspend关键字即可;

    • ROOM:DAO 方法加suspend关键字即可;

    • 自己实现挂起函数(仅特殊场景用): kotlin

      复制代码
      // 定义挂起函数:模拟网络请求
      suspend fun getUserName(): String {
          // delay是挂起函数,替代Thread.sleep,非阻塞
          delay(2000)
          return "张三"
      }
      // 协程中调用
      viewModelScope.launch {
          val name = getUserName() // 直接调用,协程会暂停2秒
          tvName.text = name
      }
4. async/await:启动有返回值的协程(并发操作)
  • 作用 :启动有返回值 的协程,支持多协程并发执行 ,适合需要同时执行多个异步操作(如同时请求 "用户信息" 和 "订单列表")的场景;

  • 用法async { 操作 }启动协程,await()等待协程完成并获取返回值(await()是挂起函数);

  • 实战示例 (并发网络请求):

    kotlin

    复制代码
    viewModelScope.launch {
        // 并发启动2个协程(同时执行,无先后顺序)
        val userDeferred = async(Dispatchers.IO) { api.getUserInfo() }
        val orderDeferred = async(Dispatchers.IO) { api.getOrderList() }
    
        // 等待两个协程均完成,获取返回值(非阻塞,协程挂起)
        val user = userDeferred.await()
        val orderList = orderDeferred.await()
    
        // 处理并发结果(主线程)
        combineData(user, orderList)
    }
  • 核心优势 :并发执行的总耗时 = 最慢的那个操作的耗时(如用户请求 2 秒,订单请求 3 秒,总耗时 3 秒),比串行执行(5 秒)效率提升一倍。

5. delay:非阻塞式延迟(替代Thread.sleep
  • 作用 :协程内的非阻塞式延迟 ,用于延迟执行操作,替代Thread.sleep
  • 性质挂起函数 ,延迟时不会阻塞线程 (线程可继续执行其他协程),而Thread.sleep会阻塞线程;
  • 用法delay(毫秒),如delay(1000)表示延迟 1 秒;
  • 注意协程中禁止使用Thread.sleep ,必须用delay

五、实战核心:协程与 Retrofit2 的结合(替代 RxJava3)

你之前搭建了 Retrofit2+OkHttp3 的网络框架,Retrofit2 对协程做了原生支持 ,无需 RxJava3 适配器,只需一行代码改造接口 ,即可在协程中直接调用,代码比 RxJava3 更简洁、更易维护。这是 Android 协程的最核心实战场景 ,也是目前生产环境的标准用法

步骤 1:改造 Retrofit2 接口(添加suspend关键字)

无需修改 Retrofit2 的任何配置(OkHttp 拦截器 / BaseUrl / 转换器均不变),只需在接口方法前添加suspend关键字 ,Retrofit 会自动将该方法转为挂起函数,可在协程中直接调用。

kotlin

复制代码
// 1. 先定义统一响应体(和你之前的BaseResponse一致)
data class BaseResponse<T>(
    val code: Int,
    val message: String,
    val data: T?
) {
    // 判断请求是否成功(根据后端实际成功码修改,如200/0)
    fun isSuccess() = code == 200
}

// 2. 改造Retrofit3接口:添加suspend关键字,直接返回BaseResponse<T>
interface UserApi {
    // 登录接口:POST请求,添加suspend关键字
    @POST("user/login")
    suspend fun login(@Body request: LoginRequest): BaseResponse<User>

    // 获取用户信息:GET请求,添加suspend关键字
    @GET("user/info")
    suspend fun getUserInfo(@Query("userId") String userId): BaseResponse<User>
}

// 登录请求体(封装参数)
data class LoginRequest(val username: String, val password: String)
// 业务数据模型
data class User(val userId: String, val name: String, val token: String)
步骤 2:仓库层封装(统一响应体校验 + 异常处理)

创建仓库层,封装接口调用逻辑,统一校验响应体、统一处理业务异常 ,给 ViewModel 提供干净的业务方法(ViewModel 无需关注响应体解析)。

kotlin

复制代码
// 网络仓库:封装所有接口调用逻辑
class NetRepository {
    // 获取Retrofit接口服务(和你之前的ApiServiceFactory一致)
    private val userApi = ApiServiceFactory.createUserApi()

    // 登录业务方法:挂起函数,供ViewModel调用
    suspend fun login(username: String, password: String): User {
        // 调用Retrofit挂起函数,执行网络请求
        val response = userApi.login(LoginRequest(username, password))
        // 统一响应体校验(和你之前的RxTransformer逻辑一致)
        if (response.isSuccess()) {
            // 成功:返回业务数据,若数据为空则抛出业务异常
            return response.data ?: throw BusinessException("用户数据为空")
        } else {
            // 失败:抛出业务异常(携带错误码和错误信息)
            throw BusinessException(response.code, response.message)
        }
    }

    // 自定义业务异常(替代你之前的NetException)
    class BusinessException(val code: Int = -1, msg: String) : Exception(msg)
}
步骤 3:ViewModel 层调用(协程版,核心)

通过viewModelScope启动协程,调用仓库的挂起函数,withContext指定 IO 线程,用try/catch统一处理所有异常(网络异常 / 业务异常 / 解析异常),代码比 RxJava3 更直观。

kotlin

复制代码
class UserViewModel : ViewModel() {
    // 仓库实例
    private val repository = NetRepository()
    // 用LiveData传递数据给View层(也可用StateFlow,协程推荐)
    private val _userLiveData = MutableLiveData<User?>()
    val userLiveData: LiveData<User?> = _userLiveData
    // 用LiveData传递异常信息
    private val _errorLiveData = MutableLiveData<String>()
    val errorLiveData: LiveData<String> = _errorLiveData

    // 登录方法:供View层调用
    fun login(username: String, password: String) {
        viewModelScope.launch {
            try {
                // IO线程执行登录请求(withContext切换线程)
                val user = withContext(Dispatchers.IO) {
                    repository.login(username, password)
                }
                // 主线程更新LiveData,View层观察更新UI
                _userLiveData.value = user
            } catch (e: ConnectException) {
                // 网络连接异常
                _errorLiveData.value = "请检查网络连接"
            } catch (e: SocketTimeoutException) {
                // 网络超时异常
                _errorLiveData.value = "网络请求超时,请稍后重试"
            } catch (e: NetRepository.BusinessException) {
                // 业务异常(如Token过期/参数错误)
                _errorLiveData.value = e.message ?: "请求失败"
            } catch (e: Exception) {
                // 未知异常
                _errorLiveData.value = "未知错误,请稍后重试"
            }
        }
    }
}
步骤 4:View 层(Activity)观察数据(无协程代码)

View 层只需观察 ViewModel 的 LiveData/StateFlow ,更新 UI 即可,无需写任何协程代码 ,符合 MVVM 的职责划分(View 层只做 UI 渲染,不处理业务逻辑)。

kotlin

复制代码
class LoginActivity : AppCompatActivity() {
    private val userViewModel by viewModels<UserViewModel>()
    private lateinit var binding: ActivityLoginBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityLoginBinding.inflate(getLayoutInflater())
        setContentView(binding.root)

        // 观察用户数据(登录成功)
        userViewModel.userLiveData.observe(this) { user ->
            user?.let {
                // 更新UI:如跳转到主页面
                Toast.makeText(this, "登录成功,欢迎${it.name}", Toast.LENGTH_SHORT).show()
                startActivity(Intent(this, MainActivity::class.java))
                finish()
            }
        }

        // 观察异常信息(登录失败)
        userViewModel.errorLiveData.observe(this) { errorMsg ->
            // 显示异常提示
            Toast.makeText(this, errorMsg, Toast.LENGTH_SHORT).show()
        }

        // 登录按钮点击事件
        binding.btnLogin.setOnClickListener {
            val username = binding.etUsername.text.toString().trim()
            val password = binding.etPassword.text.toString().trim()
            // 直接调用ViewModel方法,无需关注协程
            userViewModel.login(username, password)
        }
    }
}

六、异常处理:Android 协程的统一方案

协程的异常处理遵循 **「作用域原则」,Android 开发中 仅需掌握两种方式 **,即可覆盖所有场景,且比 RxJava3 的异常处理更简洁

1. 局部异常处理:try/catch(推荐,Android 最常用)

协程执行体中直接用try/catch捕获异常,这是 Android 协程的标准异常处理方式 ,适合单个协程的异常处理(如网络请求 / 数据库操作),也是你之前在 ViewModel 中看到的方式。

kotlin

复制代码
viewModelScope.launch {
    try {
        val data = withContext(Dispatchers.IO) { repository.getData() }
        _dataLiveData.value = data
    } catch (e: ConnectException) {
        // 网络异常
        _errorLiveData.value = "无网络"
    } catch (e: BusinessException) {
        // 业务异常
        _errorLiveData.value = e.message
    } catch (e: Exception) {
        // 兜底处理所有异常
        _errorLiveData.value = "未知错误"
    }
}
2. 全局异常处理:CoroutineExceptionHandler(批量处理)

若需要为某个作用域下的所有协程统一处理异常 (如全局网络异常提示),可使用CoroutineExceptionHandler,适合批量协程的异常处理

kotlin

复制代码
// 1. 创建全局异常处理器
val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
    // 全局处理异常(如弹全局Toast/埋点统计)
    runOnUiThread {
        Toast.makeText(applicationContext, "全局异常:${throwable.message}", Toast.LENGTH_SHORT).show()
    }
}

// 2. 启动协程时绑定异常处理器
viewModelScope.launch(coroutineExceptionHandler) {
    val data = withContext(Dispatchers.IO) { repository.getData() }
    _dataLiveData.value = data
}
  • 注意CoroutineExceptionHandler仅能捕获未被局部try/catch捕获的异常 ,若局部已用try/catch,全局处理器不会触发。

七、避坑要点:Android 协程的 8 个常见错误(必看)

1. 不要手动创建CoroutineScope

Android 开发无需手动创建CoroutineScope ,直接使用官方内置的viewModelScope/lifecycleScope即可,手动创建易导致内存泄漏(忘记取消协程)。

2. 不要在非协程中调用挂起函数

挂起函数仅能在协程中或其他挂起函数中调用,普通函数直接调用会报编译错误,解决方式:在作用域中启动协程,再调用挂起函数。

3. 不要用Thread.sleep,必须用delay

Thread.sleep阻塞线程 ,导致线程无法处理其他协程,协程中必须用delay(非阻塞)。

4. 不要在Dispatchers.Main中执行耗时操作

Dispatchers.Main是主线程,执行耗时操作会导致 ANR ,耗时操作必须放在Dispatchers.IO/Dispatchers.Default中。

5. 不要忽略协程的异常

协程中未被捕获的异常会导致应用崩溃 ,必须用try/catchCoroutineExceptionHandler捕获所有异常。

6. 不要在launch中直接嵌套launch

如需嵌套协程,直接在协程执行体中写代码即可,无需嵌套launch,嵌套launch会导致协程管理混乱。

7. 网络请求不要用lifecycleScope

lifecycleScope受 Activity 重建影响,网络请求建议用viewModelScope(生命周期更长,不受页面重建影响)。

8. 不要忘记withContext的调度器

viewModelScope/lifecycleScope中执行耗时操作时,必须用withContext(Dispatchers.IO)切换到子线程,否则会在主线程执行耗时操作,导致 ANR。

八、与 RxJava3 的对比(为什么协程是未来)

你之前用 RxJava3 搭建了响应式框架,协程作为 Android 官方推荐的方案,对比 RxJava3 有以下核心优势,也是目前生产环境逐步替换 RxJava3的原因:

特性 协程 RxJava3
语法简洁 极简,一行代码启动协程,无需复杂的适配器 / 转换器 繁琐,需要创建 Observable/Observer,配置线程切换 / 背压
内存泄漏 内置作用域自动绑定生命周期,从根本上解决 需要手动绑定生命周期(RxLifecycle/AutoDispose),易遗漏
线程切换 一行withContext实现,直观高效 需要subscribeOn/observeOn,易混淆
异常处理 原生try/catch,符合 Java/Kotlin 开发习惯 需用onError,异常链复杂,不易调试
学习成本 低,基于 Kotlin 语法,3 个核心概念即可上手 高,背压 / 操作符 / 线程调度等概念繁多,学习曲线陡峭
官方支持 Android 官方唯一推荐,与 Jetpack 深度集成 第三方库,无官方支持
性能 无额外开销,挂起 / 恢复是语法层面的操作 有额外开销,需要创建大量的 Observable/Observer 对象

总结

Android 中使用协程的核心精髓 可总结为3 句话,掌握后即可覆盖 99% 的开发场景:

  1. 作用域用内置 :直接使用viewModelScope(MVVM 首选)/lifecycleScope,无需手动创建,生命周期自动绑定,解决内存泄漏;
  2. 线程切换用withContextDispatchers.IO执行耗时操作,Dispatchers.Main更新 UI,一行代码实现,直观高效;
  3. 异步操作用挂起函数 :对接 Retrofit3/ROOM 等第三方库的挂起函数,协程中直接调用,原生try/catch处理异常。

协程是 Android 异步编程的未来 ,与 Jetpack(ViewModel/LiveData/StateFlow)深度集成,也是目前大厂 Android 开发的标准方案,替换 RxJava3 后,代码会更简洁、更易维护、更不易出 bug。

相关推荐
TRACER~852 小时前
QFIL工具烧录
android
STCNXPARM13 小时前
Linux camera之V4L2子系统详解
android·linux·camera·v4l2架构
2501_9445255414 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
不急不躁12317 小时前
Android16 GTS GtsPermissionTestcases 测试,跳过权限检查
android
符哥200819 小时前
关于用Android Compose开发成不成熟的分析
android·android jetpack
蜗牛、Z19 小时前
Android 蓝牙/Wi-Fi通信协议之:蓝牙扫描ScanCallback详解
android
黄昏晓x19 小时前
Linux----进程控制
android·linux·运维
我是阿亮啊19 小时前
android中事件分发机制
android·事件分发·事件分发机制
心前阳光20 小时前
Unity 模拟父子关系
android·unity·游戏引擎