在 Android 開發中,setClickable() 可在背景執行緒呼叫而不崩潰,但 setEnabled() 與 setVisibility() 卻會拋出 CalledFromWrongThreadException。根本原因在於後兩者會觸發 View 重繪,而 Android 規定只有 UI 執行緒(主執行緒)能操作 View 階層與觸發繪製。
setClickable() 僅修改內部旗標(mClickable),不涉及佈局或繪製流程,因此不檢查執行緒。
withContext(Dispatchers.Main) { view.visibility = View.VISIBLE }// 錯誤示範(會崩潰)
new Thread(() -> {
button.setEnabled(true); // 執行緒檢查失敗
textView.setVisibility(View.VISIBLE);
}).start();
// 正確寫法
new Thread(() -> {
// 背景運算...
runOnUiThread(() -> {
button.setEnabled(true);
textView.setVisibility(View.VISIBLE);
});
}).start();
View.post() 可避免持有 Activity 參考導致記憶體洩漏。RecyclerView + DiffUtil 或 Jetpack Compose 以減少主執行緒負擔。掌握執行緒規則,能讓 Android App 更穩定、流暢。