Handler的适用场景与使用时机?为何用其更新TextView而非普通循环?
Great question! This is one of the most fundamental concepts to grasp when working with Android UI development—let’s break it down simply:
1. Android’s UI Thread Rule: No Blocking Allowed
All UI components (like TextView) can only be modified from the main thread (UI thread). If you run a regular infinite loop directly on the main thread (say, in onCreate()), you’ll completely block it.
The main thread is responsible for handling user interactions (button taps, swipes), drawing the UI, and responding to system events. A stuck loop means none of these tasks can run, and Android will trigger an ANR (Application Not Responding) error within a few seconds—your app will freeze and the user will get a force-close prompt.
Here’s what that bad code would look like:
// ❌ DON'T DO THIS: Blocks the main thread instantly @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView timeDisplay = findViewById(R.id.tv_stopwatch); long start = System.currentTimeMillis(); while (true) { long elapsed = System.currentTimeMillis() - start; timeDisplay.setText(String.valueOf(elapsed / 1000)); } }
2. You Can’t Update UI from a Background Thread Either
You might think, "Okay, I’ll run the loop in a background thread!" But Android strictly prohibits modifying UI components from non-main threads. UI elements aren’t thread-safe—accessing them from multiple threads can cause race conditions, UI glitches, or even app crashes with a CalledFromWrongThreadException.
3. Handler Solves Both Problems
Handler is Android’s built-in tool for thread communication, specifically to safely pass UI update tasks from background threads to the main thread’s message queue. Here’s how it works for a stopwatch:
- You run the timing logic in a background thread (or use
postDelayed()to avoid a dedicated thread). - Every time you need to update the
TextView, you use theHandlerto post aRunnableto the main thread’s message queue. - The main thread processes this
Runnablein its own time, without blocking other critical tasks.
Here’s a simplified correct example:
// ✅ Safe and non-blocking private Handler mainHandler = new Handler(Looper.getMainLooper()); private TextView timeDisplay; private long startTime; private Runnable updateTimer = new Runnable() { @Override public void run() { long elapsed = System.currentTimeMillis() - startTime; timeDisplay.setText(String.valueOf(elapsed / 1000)); // Schedule the next update in 1 second mainHandler.postDelayed(this, 1000); } }; // Start the stopwatch startTime = System.currentTimeMillis(); mainHandler.post(updateTimer);
This way, the main thread stays free to handle user interactions, and the UI updates happen safely in the correct thread.
(Side note: Modern Android development often uses Coroutines or View.postDelayed() instead of raw Handler, but the core principle—keeping UI updates on the main thread without blocking it—remains the same.)
内容的提问来源于stack exchange,提问作者Deeraj Theepshi

