Android Jetpack Compose 不允許在主執行緒上操作 (協同程式 Coroutines)

在執行程式時出現以下錯誤:
    
java.lang.RuntimeException: Unable to start activity ComponentInfo{MainActivity}: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
    

意思是不能夠在主執行緒上面執行可能需要長時間處理的任務,會造成介面沒有回應。
有一個很簡單的解決方式,就是透過 協同程式 (Coroutines) 執行。

在 @Composable 標記的方法中可以使用 launch(Dispatchers.IO) 切換到 Dispatchers.IO 線程進行讀寫操作
    
@Composable
fun MainPage() {

    LaunchedEffect(Unit) {
        launch(Dispatchers.IO) {

            // 查詢資料庫資料
            val all = db.wordDao().getAll()

        }
    }

}
    

如果要更新介面還可以在這裡面再切回主線程進行操作:
    
@Composable
fun MainPage() {

    LaunchedEffect(Unit) {
        launch(Dispatchers.IO) {

            // 查詢資料庫資料
            val all = db.wordDao().getAll()
            
            launch(Dispatchers.Main) {
                // 更新 UI
            }

        }
    }

}
    

還可以使用 withContext 來簡化,反覆橫跳
    
@Composable
fun MainPage() {

    LaunchedEffect(Unit) {
        launch(Dispatchers.IO) {

            // 背景執行緒

            withContext(Dispatchers.Main){
                // 主執行緒
            }

            // 背景執行緒

            withContext(Dispatchers.Main){
                // 主執行緒
            }

        }
    }

}
    



參考資料:
Android Developers - Kotlin coroutines on Android
Android Developers - Use Kotlin coroutines with lifecycle-aware components

留言