1. Handler and Looper (Traditional Android Way)
// Create Handler on main thread
val mainHandler = Handler(Looper.getMainLooper())
// Background thread sends message to main thread
Thread {
val result = fetchData()
mainHandler.post {
textView.text = result // Runs on main thread
}
}.start()
2. Handler with Messages
val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
when (msg.what) {
MSG_UPDATE_PROGRESS -> {
progressBar.progress = msg.arg1
}
MSG_COMPLETE -> {
val result = msg.obj as String
textView.text = result
}
}
}
}
// From background thread
Thread {
for (i in 0..100) {
handler.sendMessage(Message.obtain().apply {
what = MSG_UPDATE_PROGRESS
arg1 = i
})
}
handler.sendMessage(Message.obtain().apply {
what = MSG_COMPLETE
obj = "Done!"
})
}.start()
3. runOnUiThread() (Activity only)
Thread {
val data = fetchData()
runOnUiThread {
textView.text = data
}
}.start()
4. View.post()
Thread {
val data = fetchData()
textView.post {
textView.text = data
}
}.start()
5. LiveData (Lifecycle-aware)
class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> = _data
fun fetchData() {
viewModelScope.launch(Dispatchers.IO) {
val result = repository.getData()
_data.postValue(result) // Thread-safe!
}
}
}
// In Activity/Fragment
viewModel.data.observe(this) { result ->
textView.text = result // Automatically on main thread
}
6. Kotlin Coroutines (Recommended)
lifecycleScope.launch {
val data = withContext(Dispatchers.IO) {
fetchData() // Background thread
}
// Automatically back on main thread
textView.text = data
}
7. Flow (Reactive Streams)
fun dataFlow(): Flow<String> = flow {
emit(fetchData())
}.flowOn(Dispatchers.IO)
// Collect on main thread
lifecycleScope.launch {
dataFlow().collect { data ->
textView.text = data
}
}
| Method | Lifecycle-aware | Modern | Recommended |
|---|---|---|---|
| Handler | No | No | Legacy code |
| runOnUiThread | No | No | Quick fixes |
| LiveData | Yes | Yes | MVVM |
| Coroutines | Yes* | Yes | โ Best |
| Flow | Yes* | Yes | โ Reactive |
*With lifecycleScope/viewModelScope
Use Coroutines with lifecycleScope or viewModelScope for automatic lifecycle management and clean, readable code.
Mark this when you can explain the answer in your own words.
Help fellow developers prepare for interviews
Sharing helps the Android community grow ๐