Android协程 vs. 传统线程/线程池:现代化异步编程的演进
目录
-
- 协程的四大核心优势
-
- 1. 🪶 轻量级线程
- 2. 🏗️ 结构化并发
- 3. ✨ 简化异步代码
- 4. ⏸️ 挂起恢复机制
- Android协程的三大调度器
-
- Dispatchers.Main
- Dispatchers.IO
- Dispatchers.Default
- 实战对比:网络请求+数据处理
- 性能对比表格
- 最佳实践
-
- 1. 正确使用调度器
- 2. 合理使用async/await
- 3.异常处理
- 结论
在Android开发中,处理异步任务一直是个核心话题。从最初的Thread和Handler,到AsyncTask,再到线程池,如今协程已成为官方推荐的异步解决方案。让我们深入探讨协程为何能成为Android异步编程的首选。该文也是针对 Android线程与线程池面试题总结文中4.2节的解答。
协程的四大核心优势
1. 🪶 轻量级线程
协程在用户态进行调度,而非操作系统级别,这使得协程的创建和切换成本极低。
传统线程方式
// 每个线程都需要约1MB内存,创建和切换成本高
fun fetchDataWithThreads(){Thread{val data = fetchFromNetwork()runOnUiThread{updateUI(data)}}.start()
}//使用线程池
private val executor = Executors.newFixedThreadPool(4)
fun fetchWithThreadPool(){executor.execute{val data = fetchFromNetwork()runOnUiThread{updateUI(data)}}
}
协程方式
// 数千个协程可以在单个线程上运行
fun fetchDataWithCoroutine() = viewModelScope.launch {val data = withContext(Dispatchers.IO){fetchFromNetwork() //挂起函数}updataUI(data)// 自动回到住线程
}
内存对比
- 线程: 每个线程约1MB栈内存,1000个线程≈ 1GB内存
- 协程:每个协程约几十KB,1000个协程 ≈ 几十MB内存
2. 🏗️ 结构化并发
协程通过作用域(CoroutineScope)管理生命周期,避免内存泄漏和任务丢失。
class MyViewModel : ViewModel() {// ViewModel自动提供viewModelScopefun loadUserData() {viewModelScope.launch {// 当ViewModel清除时,所有在此作用域启动的协程自动取消val user = fetchUser()val posts = fetchUserPosts(user.id)updateUI(user, posts)}}
}// Activity/Fragment中的使用
class MainActivity : AppCompatActivity() {private lateinit var job: Joboverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 方式1:使用lifecycleScopelifecycleScope.launch {// 当Activity销毁时自动取消loadData()}// 方式2:手动管理job = 