開發者常寫出如下程式碼,期望「延遲 3 秒設定旗標 → 再執行 if 區塊」:
Permissions_flag = false;
new Handler().postDelayed(new Runnable() {
@Override public void run() {
Permissions_flag = true;
Log.e("handler", "start");
}
}, 3000);
if (Permissions_flag) { // 此處立即執行,flag 仍為 false
// 權限處理邏輯
}
結果:if 區塊立即執行,完全不等待 3 秒延遲,因為 postDelayed 只是將 Runnable 排入主執行緒訊息佇列,當前執行緒繼續往下跑。
postDelayed 是非同步操作:排程未來執行,當下不阻塞。Looper 循環處理訊息佇列。new Handler(Looper.getMainLooper()).postDelayed(() -> {
Permissions_flag = true;
Log.e("handler", "start");
// 直接在這裡執行原本 if 區塊的邏輯
handlePermissions();
}, 3000);
lifecycleScope.launch {
delay(3000) // 非阻塞暫停 3 秒
Permissions_flag = true
handlePermissions() // 這裡會在 3 秒後執行
}
需在 build.gradle 引入 androidx.lifecycle:lifecycle-runtime-ktx。
Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
handlePermissions();
}
}
};
new Thread(() -> {
try { Thread.sleep(3000); } catch (InterruptedException ignored) {}
handler.sendEmptyMessage(1);
}).start();
嚴禁在主執行緒使用,會導致 ANR。若在 Worker Thread 中需等待:
CountDownLatch latch = new CountDownLatch(1);
new Handler(Looper.getMainLooper()).postDelayed(() -> {
Permissions_flag = true;
latch.countDown();
}, 3000);
try { latch.await(); } catch (InterruptedException ignored) {}
handlePermissions();
Permissions_flag 協調非同步流程,極易產生競態條件。Handler(Looper.getMainLooper()) 確保執行緒正確。postDelayed 不會阻塞當前執行緒,這是 Android 非同步程式設計的基礎特性。理解「排程 ≠ 等待」,將後續邏輯封裝在回呼或協程中,才能寫出正確的循序執行程式碼。