常見場景:獲取驗證碼按鈕點擊後 60 秒倒計時,期間按鈕不可用、顯示剩餘秒數,結束後恢復。本文對比兩種主流實現方式。
Android 專用工具類,封裝了 Handler 機制,API 簡潔,自動處理生命週期。
private class TimeCount extends CountDownTimer {
public TimeCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisUntilFinished) {
btn.setClickable(false);
btn.setText("(" + millisUntilFinished / 1000 + ")秒後重試");
}
@Override
public void onFinish() {
btn.setClickable(true);
btn.setText("獲取驗證碼");
}
}
// 使用
TimeCount timer = new TimeCount(60_000, 1000);
timer.start();
cancel() 方法,配合 onDestroy() 釋放資源,防內存洩漏。適用於需要高度自定義邏輯、或非 UI 執行緒場景。
private boolean timeFlag = true;
private Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override public void handleMessage(Message msg) {
if (msg.what > 0) {
btn.setText("(" + msg.what + ")秒後重試");
} else {
btn.setClickable(true);
btn.setText("獲取驗證碼");
}
}
};
// 啟動執行緒
new Thread(() -> {
for (int i = 59; i >= 0 && timeFlag; i--) {
try { Thread.sleep(1000); }
catch (InterruptedException e) { e.printStackTrace(); }
mHandler.obtainMessage(i).sendToTarget();
}
}).start();
// 銷毀時釋放
@Override protected void onDestroy() {
super.onDestroy();
timeFlag = false; // 停止執行緒迴圈
mHandler.removeCallbacksAndMessages(null); // 清空訊息佇列
}
onDestroy 中設置標誌位 false 並清空 Handler,否則執行緒與訊息佇列殘留導致內存洩漏。Looper.getMainLooper() 確保。| 維度 | CountDownTimer | Handler + Thread |
|---|---|---|
| 代碼量 | 極少 | 較多 |
| 生命週期管理 | 內建 cancel() | 手動管理標誌位 + Handler 清理 |
| 靈活度 | 固定間隔回調 | 完全可控(動態間隔、暫停/繼續) |
| 適用場景 | 標準倒計時、驗證碼 | 複雜定時邏輯、遊戲迴圈、後台任務 |