Your app crashes with a CalledFromWrongThreadException:
android.view.ViewRootImpl$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.
Android's View system is not thread-safe. If multiple threads modify views simultaneously:
So Android enforces that only the main thread touches views.
Thread {
val data = fetchDataFromNetwork()
textView.text = data // ๐ฅ CRASH!
}.start()
// Inside View's internal code
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views."
);
}
}
1. runOnUiThread()
Thread {
val data = fetchData()
runOnUiThread {
textView.text = data // โ
Safe
}
}.start()
2. Handler
val handler = Handler(Looper.getMainLooper())
Thread {
val data = fetchData()
handler.post {
textView.text = data // โ
Safe
}
}.start()
3. View.post()
Thread {
val data = fetchData()
textView.post {
textView.text = data // โ
Safe
}
}.start()
4. Coroutines (Best)
lifecycleScope.launch {
val data = withContext(Dispatchers.IO) {
fetchData()
}
textView.text = data // โ
Safe, already on Main
}
5. LiveData
// In ViewModel
_liveData.postValue(data) // Thread-safe
// In Activity (observes on main thread)
liveData.observe(this) { textView.text = it }
A few View methods can be called from any thread:
View.postInvalidate()View.postInvalidateDelayed()View.post()View.postDelayed()These internally post to the main thread's Handler.
Always update UI from the main thread. Use the modern tools (Coroutines, LiveData) that handle this automatically.
Mark this when you can explain the answer in your own words.
Help fellow developers prepare for interviews
Sharing helps the Android community grow ๐