I’ve been working as an Android developer for four years and have contributed to two major Microsoft apps with 10M and 1B+ downloads. I also published a small app on the Play Store in just a week and have invested in improving my skills by reading Android-related books and taking courses. With this background, I felt confident about my expertise and began applying for Android roles.
However, I faced multiple rejections during interviews. The interviewers focused heavily on the internal workings of Android APIs—details beyond my practical usage, like understanding the mechanics behind coroutines rather than just knowing how to use them.
Recently, I came across a course by a highly experienced Android instructor (10+ years) who has transitioned to full-time teaching. His demo session stood out because of its focus on internal details, experiments, and case studies. It resonated with me, and I believe it could help me not only crack interviews but also become part of the top 1% of Android developers globally.
The challenge is the cost: ₹40,000 upfront (25% of my monthly salary) and ₹2 lakhs (10% of my annual salary) after securing a new job. It’s a significant investment, and I’m wondering:
As a fairly senior Android engineer, I don't know the internals of many of the newer frameworks. And I honestly don't need to: the skills needed to grow to senior and beyond is heavily skewed towards non-technical skills. If I need to learn it in order to accomplish a critical task or goal for the team/company, I will learn it. Else, the knowledge doesn't give me that much value.
The course could be worthwhile if:
You are smart to be a bit skeptical since most programs won't offer the above.
You already have some major accomplishments as an Android engineer. Have you tried changing your approach to applying for jobs before the major time + financial commitment of this course?
From first glance, the course doesn't seem worth it. I think it's much better to organize all the ways you've been failing Android interviews, look for patterns, and then honestly just use ChatGPT (and Google) to fill in those knowledge gaps. For your coroutines example, ChatGPT's explanation is decent if you just ask it "What are the mechanics of coroutines in Android?".
Coroutines in Android (and Kotlin in general) provide a lightweight way to manage background threads and perform asynchronous tasks without blocking the main thread. They're built on the idea of suspending functions, which can pause execution without blocking a thread and resume later.
Here's a breakdown of the core mechanics of coroutines in Android:
A coroutine is a function that can be paused (suspended) and resumed later.
Defined using suspend
keyword or launched with builders like launch
, async
, or runBlocking
.
suspend fun fetchData() {
// Suspends without blocking the thread
delay(1000)
println("Data fetched")
}
launch
: Fire-and-forget, returns a Job
, used when result isn’t needed.
async
: Returns a Deferred<T>
, used when a result is expected (like a Future
).
runBlocking
: Blocks the current thread until coroutine finishes; used for testing or main functions.
GlobalScope.launch {
val data = fetchData()
}
Dispatchers define where (i.e., on which thread) the coroutine runs:
Dispatchers.Main
: Main thread (UI operations)
Dispatchers.IO
: For I/O operations (network, database)
Dispatchers.Default
: For CPU-intensive work
Dispatchers.Unconfined
: Starts in the current thread, but can resume elsewhere
CoroutineScope(Dispatchers.IO).launch {
val result = fetchFromNetwork()
withContext(Dispatchers.Main) {
updateUI(result)
}
}
A CoroutineScope manages the lifecycle of coroutines:
lifecycleScope
and viewModelScope
to tie coroutine lifetimes to components.// In a ViewModel
viewModelScope.launch {
val data = repository.getData()
_uiState.value = data
}
Functions marked with suspend
can be paused and resumed:
Cannot be called from regular functions.
Can call other suspending functions.
Do not block threads.
Coroutines launched within a scope are automatically cancelled when the scope is cancelled (e.g., when an Activity is destroyed). This prevents memory leaks and orphaned background work.
Coroutines are cancellable:
Use isActive
or ensureActive()
to check/cancel cooperatively.
Use withTimeout()
or withTimeoutOrNull()
for automatic timeouts.
Use try-catch
blocks or CoroutineExceptionHandler
:
launch
propagates exceptions to its parent.
async
requires await()
to observe exceptions.
val handler = CoroutineExceptionHandler { _, exception ->
Log.e("CoroutineError", exception.message ?: "Unknown error")
}
CoroutineScope(Dispatchers.IO + handler).launch {
throw Exception("Oops!")
}
Concept | Description |
---|---|
suspend | Marks a function as pausable/resumable |
launch | Starts a coroutine that returns a Job |
async | Starts a coroutine that returns a Deferred |
Dispatcher | Determines thread execution context |
CoroutineScope | Manages coroutine lifecycle |
viewModelScope / lifecycleScope | Android-specific scopes |
withContext | Switches context (like threads) within a coroutine |
At the end of the day, interviews are inherently random (and dumb), so don't worry too much about the straggler interview asking you dumb trivia nobody else did. It's really hard to control for those.
Thanks — I got your point. Unfortunately, the link isn’t accessible; could you share an updated one?
I just inlined it into my original comment. I assume that's what I got before haha.