Android
UI thread
View hierarchy
Multithreading
App development

Android Only the original thread that created a view hierarchy can touch its views.

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Android development, a common rule developers encounter is: "Only the original thread that created a view hierarchy can touch its views." This principle is central to the design of the Android UI framework, where the main thread, also known as the UI thread, is responsible for managing all UI operations. Understanding this rule is crucial for building responsive and crash-free Android applications.

The Main Thread

The main thread is where Android applications run by default. It is responsible for processing events, updating UI controls, and executing lifecycle callbacks for activities and fragments. The Android operating system enforces strict single-threaded access to UI operations to prevent concurrency issues. Such issues can lead to inconsistent UI states, application crashes, or difficult-to-debug threading issues.

Why UI Operations Are Limited to the Main Thread

  1. Concurrency Control: Allowing multiple threads to modify UI elements could lead to race conditions where the threads serve competing requests at the same time.
  2. Avoiding Complex Synchronizations: Without this limitation, developers would need to implement complex synchronization mechanisms like locks, which could lead to deadlocks or performance issues.
  3. Simplicity: Limiting UI updates to the main thread streamlines the UI programming model for developers, as they do not need to concern themselves with the coordination between multiple threads for UI rendering.

Violating the Rule

If a background thread attempts to modify a view, the app will throw an android.view.ViewRootImpl$CalledFromWrongThreadException with a message stating that only the original thread that created the view hierarchy can touch its views. Consider the following example:

java
1new Thread(new Runnable() {
2    @Override
3    public void run() {
4        // This code will run on a separate thread
5        textView.setText("Hello from a different thread!"); // This will throw an exception
6    }
7}).start();

Correct Handling With Handler

The most common way to update UI from a background thread is by using an Android Handler. Handler associated with the main thread can post Runnable tasks to the main thread's message queue. Here's how you can safely update a TextView from a background thread:

java
1Handler mainHandler = new Handler(Looper.getMainLooper());
2new Thread(new Runnable() {
3    @Override
4    public void run() {
5        // Simulated network call or other background task
6        mainHandler.post(new Runnable() {
7            @Override
8            public void run() {
9                // Update UI elements safely
10                textView.setText("Updated from main thread!");
11            }
12        });
13    }
14}).start();

Using AsyncTask

AsyncTask was traditionally used to perform operations in the background and publish results on the UI thread. While it is deprecated as of Android 11, it’s important to understand it for older codebases:

java
1private class UpdateTask extends AsyncTask<Void, Void, String> {
2    @Override
3    protected String doInBackground(Void... voids) {
4        // Perform background operations
5        return "Result from background";
6    }
7
8    @Override
9    protected void onPostExecute(String result) {
10        // Update UI with the result
11        textView.setText(result);
12    }
13}
14
15// Executing AsyncTask
16new UpdateTask().execute();

Using Other Concurrency Frameworks

  1. Java ExecutorService: Allows managing a pool of threads and is suitable for complex operations.
  2. RxJava: Enables reactive programming patterns, simplifying threading with observable streams and schedulers.
  3. Kotlin Coroutines: Provides an expressive way to handle concurrency, leveraging syntax like launch and async to manage background work efficiently.

Table Summary: Key Points

AspectDetails
Main ThreadDefault thread for UI components
Rule EnforcementPrevents race conditions and synchronization complexity
Common Violation ExceptionViewRootImpl$CalledFromWrongThreadException
UI Thread UpdatersHandler, AsyncTask (deprecated), ExecutorService, etc.
Modern AlternativesRxJava, Kotlin Coroutines

Conclusion

The rule "Only the original thread that created a view hierarchy can touch its views" is a fundamental aspect of Android development, ensuring that applications remain stable and responsive. Although this may seem restrictive, Android offers various mechanisms to safely update the UI from background threads. Understanding and applying these techniques is pivotal for developing efficient and reliable Android applications.


Course illustration
Course illustration

All Rights Reserved.