首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 定時更新 UI 的正確姿勢:Handler 替代 Timer 避免執行緒問題

     編輯:程式設計綜合問答

問題回顧

開發者嘗試使用 java.util.Timer 每 5 秒更新一次 TextView,代碼如下:

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        textTitle.setText(title); // 直接在背景執行緒操作 UI
        textArtist.setText(artist);
    }
}, 0, 5000);

結果只有第一次更新成功,後續無反應,且 Logcat 可能出現 CalledFromWrongThreadException。

原因分析

  1. UI 操作必須在主執行緒:TimerTask.run() 運行於背景執行緒,直接調用 setText() 違反 Android 單執行緒模型。
  2. Thread.sleep() 會阻塞背景執行緒,但不影響主執行緒,導致邏輯混亂。
  3. Timer 任務異常時會終止整個排程器,後續任務不再執行。

推薦方案:Handler + postDelayed

Handler 綁定主執行緒 Looper,確保 Runnable 在 UI 執行緒運行:

private static final int MSG_UPDATE_UI = 1;
private static final long UPDATE_INTERVAL = 5000;

private final Handler uiHandler = new Handler(Looper.getMainLooper(), msg -> {
    if (msg.what == MSG_UPDATE_UI) {
        textTitle.setText(title);
        textArtist.setText(artist);
        // 循環發送下一次更新
        uiHandler.sendEmptyMessageDelayed(MSG_UPDATE_UI, UPDATE_INTERVAL);
        return true;
    }
    return false;
});

@Override
protected void onResume() {
    super.onResume();
    uiHandler.sendEmptyMessageDelayed(MSG_UPDATE_UI, UPDATE_INTERVAL);
}

@Override
protected void onPause() {
    super.onPause();
    uiHandler.removeMessages(MSG_UPDATE_UI); // 防止洩漏與崩潰
}

現代替代方案:Kotlin Coroutines / Flow

若專案使用 Kotlin,結構化並發更簡潔:

lifecycleScope.launch {
    while (isActive) {
        withContext(Dispatchers.Main) {
            textTitle.text = title
            textArtist.text = artist
        }
        delay(5000)
    }
}

生命周期感知自動取消,無需手動移除回調。

其他可行方案對比

方案優點缺點
Handler + postDelayedAPI 兼容性好,輕量需手動管理生命周期
ScheduledExecutorService + runOnUiThread標準 Java API樣板代碼多
RxJava interval + observeOn函數式鏈式調用引入重型依賴
Kotlin Coroutines結構化並發,生命周期綁定需 Kotlin 環境

總結

拋棄 Timer 進行 UI 定時更新,改用 Handler 或協程,嚴守「主執行緒操作 UI」鐵律,並妥善處理 Activity/Fragment 生命周期,才能實現穩定、無洩漏的週期性界面刷新。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved