How do you make a network request in an Activity using coroutines?

This tests main thread safety and coroutine dispatchers. A strong answer cites NetworkOnMainThreadException, uses lifecycleScope, and switches to Dispatchers.IO. Red flag: suggesting Dispatchers.Main for the network call or omitting the exception entirely.
What's really being asked
This question checks three things in order. First, do you know that Android forbids network IO on the main thread to keep the UI responsive. Second, do you understand how Kotlin Coroutines integrate with Android lifecycle-aware components so you do not leak memory. Third, do you know which dispatcher is optimized for blocking IO versus CPU work versus UI updates. Senior interviewers care less about syntax and more about whether you understand why the main thread must stay free and how structured concurrency prevents lifecycle leaks.
The full answer
A strong response hits four points in order. First, name the exact failure mode: on API 11 and above you get a NetworkOnMainThreadException, and even if you bypass it with StrictMode the UI will jank or ANR because the thread is blocked waiting on sockets. Second, state the coroutine entry point: use lifecycleScope in an Activity or viewModelScope in a ViewModel so the coroutine is automatically cancelled when the scope dies. Third, specify the dispatcher: move the blocking network call into withContext(Dispatchers.IO) because IO is backed by a pool of threads designed for blocking operations like HTTP requests and disk reads. Fourth, mention that result updates must happen back on Dispatchers.Main, which is the default when the outer scope is lifecycleScope, so you can safely set text or swap adapters after the withContext block finishes.
The mistakes people make
Red flags that downgrade a candidate include four patterns. One, suggesting Dispatchers.Default for a network call; Default is tuned for CPU-intensive work and a smaller thread pool, so blocking it with network waits hurts performance. Two, suggesting Dispatchers.Main for the request itself; this just moves the blocking problem into a coroutine and still freezes the UI. Three, proposing legacy solutions like AsyncTask or raw Thread without lifecycle awareness; these leak if the Activity finishes before the response arrives. Four, forgetting to mention cancellation or exception handling, which signals you have not shipped coroutines in production.
What usually comes next
Interviewers often push deeper with three angles. They may ask how you handle configuration changes while a request is in flight, which leads to ViewModel, retained state, and repeating vs non-repeating lifecycles. They may ask how you structure sequential or parallel network calls, which tests your knowledge of async, await, and supervisorScope. They may also ask about error handling and retries, which reveals whether you use runCatching, CoroutineExceptionHandler, or higher-level libraries like Retrofit with suspend functions.
A concrete example
Imagine a button click that fetches a user profile. Inside the click listener you write lifecycleScope.launch. The launch block starts on Dispatchers.Main, so you can show a loading spinner immediately. Then you wrap retrofit.getUser() inside withContext(Dispatchers.IO). The main thread is freed, the spinner keeps animating, and the IO thread pool handles the HTTP handshake. Once the response returns, the coroutine resumes on Main automatically and you populate the TextViews. If the user rotates the phone and the Activity is destroyed, lifecycleScope cancels the coroutine so you do not update a dead context.
Interview question
Which combination safely performs a network request in an Activity coroutine without blocking the UI or leaking memory?
- a.lifecycleScope and Dispatchers.IOCorrect
- b.lifecycleScope and Dispatchers.Main
- c.lifecycleScope and Dispatchers.Default
- d.GlobalScope and Dispatchers.IO
Why? this is the answer
lifecycleScope automatically cancels the coroutine when the Activity is destroyed, preventing memory leaks, and Dispatchers.IO is backed by a thread pool designed for blocking network operations. Dispatchers.Default is tuned for CPU-intensive work, so using it for blocking HTTP requests hurts performance, while GlobalScope ignores the Activity lifecycle entirely.
Just read this? Test yourself on what you have been reading.
Read the original → developer.android.com
- #android
- #kotlin
- #coroutines
- #main-thread
- #networking
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on android — each one lists the topics its interview covers.
See open roles