協程是 Kotlin 提供的一套簡化異步編程的輕量級線程操作框架,特別適合 Android 開發中的異步任務處理。以下是 Android 開發中需要掌握的協程核心知識點:
1. 協程基礎概念
1.1 協程是什么
輕量級線程:比線程更高效,可以在單個線程中運行多個協程
可掛起恢復:可以在不阻塞線程的情況下掛起和恢復執行
結構化并發:提供更好的生命周期管理和錯誤處理機制
1.2 基本組件
// 啟動協程的三種方式
launch { /* 啟動不返回結果的協程 */ }
async { /* 啟動可返回結果的協程 */ }
runBlocking { /* 阻塞當前線程直到協程完成 */ }
2. 協程構建器
2.1 基本構建器
// 在ViewModel中啟動協程
viewModelScope.launch {// 協程體
}// 在Activity/Fragment中啟動協程
lifecycleScope.launch {// 自動跟隨生命周期取消
}// 全局協程
GlobalScope.launch { // 不推薦在Android中使用,容易內存泄漏
}
2.2 帶返回值的構建器
val deferred = viewModelScope.async {delay(1000)"Result"
}// 獲取結果
val result = deferred.await()
3. 協程上下文與調度器
3.1 常用調度器
Dispatchers.Main // 主線程,更新UI
Dispatchers.IO // IO操作
Dispatchers.Default // CPU密集型計算
Dispatchers.Unconfined // 不指定線程(不推薦)
3.2 上下文組合
viewModelScope.launch(Dispatchers.IO + CoroutineName("MyCoroutine")) {println("Running in ${Thread.currentThread().name}")
}
4. 協程取消與異常處理
4.1 取消協程
val job = viewModelScope.launch {repeat(1000) { i ->ensureActive() // 檢查是否被取消delay(500)println("Job: I'm sleeping $i ...")}
}// 取消協程
job.cancel()
4.2 異常處理
viewModelScope.launch {try {val result = withContext(Dispatchers.IO) {fetchData() // 可能拋出異常}} catch (e: Exception) {// 處理異常}
}// 使用SupervisorJob防止異常傳播
val scope = CoroutineScope(SupervisorJob())
5. 協程與Android架構組件
5.1 ViewModel集成
class MyViewModel : ViewModel() {fun fetchData() {viewModelScope.launch {try {val data = repository.getData()_uiState.value = UiState.Success(data)} catch (e: Exception) {_uiState.value = UiState.Error(e.message)}}}
}
5.2 Lifecycle集成
class MyActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)lifecycleScope.launch {repeatOnLifecycle(Lifecycle.State.STARTED) {// 只在STARTED狀態收集流viewModel.uiState.collect { state ->updateUI(state)}}}}
}
6. 協程與網絡請求
6.1 Retrofit集成
interface ApiService {@GET("users/{id}")suspend fun getUser(@Path("id") userId: String): User
}// 使用
viewModelScope.launch {try {val user = apiService.getUser("123")_user.value = user} catch (e: Exception) {_error.value = e.message}
}
6.2 并行請求
viewModelScope.launch {val userDeferred = async { apiService.getUser(userId) }val postsDeferred = async { apiService.getPosts(userId) }val user = userDeferred.await()val posts = postsDeferred.await()_result.value = UserWithPosts(user, posts)
}
7. 協程與Room數據庫
7.1 DAO定義
@Dao
interface UserDao {@Insertsuspend fun insert(user: User)@Query("SELECT * FROM users")fun getAllUsers(): Flow<List<User>>
}
7.2 使用示例
viewModelScope.launch {// 插入數據userDao.insert(User(name = "John"))// 觀察數據變化userDao.getAllUsers().collect { users ->_users.value = users}
}
8. 協程與Flow
8.1 創建Flow
fun countDownFlow(): Flow<Int> = flow {val countDownFrom = 10for (i in countDownFrom downTo 0) {delay(1000)emit(i)}
}
8.2 收集Flow
viewModelScope.launch {countDownFlow().collect { time ->_countDown.value = time}
}
8.3 Flow操作符
viewModelScope.launch {(1..5).asFlow().filter { it % 2 == 0 }.map { it * it }.collect { println(it) } // 輸出 4, 16
}
9. 協程最佳實踐
避免GlobalScope:使用viewModelScope或lifecycleScope
主線程安全:使用withContext切換調度器
取消傳播:確保協程可以正確取消
異常處理:為重要操作添加try-catch
避免阻塞:使用delay而非Thread.sleep
測試:使用TestCoroutineDispatcher進行單元測試
10. 協程測試
@ExperimentalCoroutinesApi
class MyViewModelTest {@get:Ruleval coroutineRule = MainCoroutineRule()@Testfun `test data loading`() = runTest {val viewModel = MyViewModel(FakeRepository())viewModel.loadData()advanceUntilIdle() // 等待所有協程完成assertEquals(expectedData, viewModel.uiState.value)}
}@ExperimentalCoroutinesApi
class MainCoroutineRule : TestWatcher() {val testDispatcher = StandardTestDispatcher()override fun starting(description: Description) {Dispatchers.setMain(testDispatcher)}override fun finished(description: Description) {Dispatchers.resetMain()}
}
總結
Kotlin協程為Android異步編程提供了強大的解決方案,通過掌握這些核心知識點,您可以:
簡化異步代碼
避免回調地獄
更好地管理資源
編寫更易測試的代碼
實現響應式UI更新
在實際開發中,建議結合ViewModel、LiveData/Flow和Retrofit等組件使用協程,構建更健壯的Android應用架構。