What Android Interviews Focus On
Android interviews test deep platform knowledge beyond basic app development. Companies probe Kotlin coroutines interview understanding, Jetpack Compose architecture, fragment lifecycle management, and modern Android architecture patterns like MVVM. You’ll write coroutine code handling exceptions, design composable UI components, and explain how ViewModel survives configuration changes. Preparing for broader tech interviews? Check our comprehensive technical interview guide.
These Android developer interview questions cover Kotlin language features (sealed classes, inline functions, higher-order functions), coroutine patterns (launch vs async, Flow vs StateFlow), Jetpack Compose questions testing declarative UI understanding, and Android fragments interview scenarios involving lifecycle and communication. Modern Android development emphasizes Jetpack libraries, structured concurrency, and reactive patterns replacing older approaches like AsyncTask and Java threading.
Kotlin Coroutines & Async Programming
Q: Explain the difference between launch and async in Kotlin coroutines.
launch starts a coroutine that doesn’t return a result, used for fire-and-forget operations. It returns a Job you can cancel. async returns a Deferred<T> representing a future result accessed via await(). Use launch for side effects like logging or UI updates. Use async when you need return values, especially for parallel operations where multiple async calls await together.
Q: What is a suspend function and how does it work?
Suspend functions can pause execution without blocking threads, enabling non-blocking asynchronous code. The suspend keyword marks functions callable only from coroutines or other suspend functions. Under the hood, the compiler transforms suspend functions using continuation-passing style. When a suspend function pauses at an await point, it returns control to the coroutine scheduler which can execute other work on that thread.
Q: Explain the difference between Flow, StateFlow, and SharedFlow.
Flow is a cold stream that starts emitting only when collected, creating new executions per collector. StateFlow is a hot stream holding a single current value, always emitting the latest state to new collectors. SharedFlow is a hot stream that can emit multiple values to multiple collectors configured for replay behavior. Use Flow for one-time operations, StateFlow for UI state management, SharedFlow for events where multiple collectors need the same emissions.
Q: How do you handle exceptions in coroutines?
Use try-catch blocks around suspend function calls for local handling. For structured exception handling, use CoroutineExceptionHandler attached to coroutine scope. SupervisorScope prevents child coroutine failures from canceling siblings, useful for independent UI operations. Always handle exceptions in async coroutines at the await() call, not launch point. ViewModelScope automatically cancels coroutines on ViewModel clearing preventing leaks.
💡 Pro tip: Interviewers test coroutine understanding with debugging questions. “Why does this coroutine never complete?” reveals whether you understand structured concurrency, dispatcher selection, and proper scope management versus just syntax.
Jetpack Compose & Declarative UI
Q: What is recomposition in Jetpack Compose and how do you optimize it?
Recomposition automatically updates UI when state changes, re-executing composable functions. Compose intelligently skips unchanged composables through positional memoization. Optimize by using remember for expensive calculations, deriving state with derivedStateOf to prevent unnecessary recompositions, and ensuring stable parameters through data classes or @Stable annotation. Avoid creating new lambda instances in composable body, use remember { {} } for callbacks.
Q: Explain the difference between remember and rememberSaveable.
remember stores values in memory surviving recompositions but lost on configuration changes (rotation). rememberSaveable persists values across process death using Android’s saved instance state mechanism. Use remember for derived state or objects that reconstruct cheaply. Use rememberSaveable for user input, scroll positions, or state that should survive rotation. Only types supported by Bundle work with rememberSaveable directly.
Q: How do you handle side effects in Jetpack Compose?
LaunchedEffect runs suspend functions tied to composable lifecycle, useful for one-time operations on composition. DisposableEffect registers listeners or subscriptions cleaned up when composable leaves composition. SideEffect executes non-suspend code after successful recomposition. rememberCoroutineScope provides scope for event-driven suspend calls. Choose based on lifecycle requirements and whether operation is suspend or not.
Q: What is unidirectional data flow in Compose architecture?
State flows down from ViewModel to composables as parameters. Events flow up from composables to ViewModel as callbacks. UI renders based on current state without directly mutating it. This pattern prevents inconsistent UI states and makes debugging easier since state changes happen in one place. ViewModel holds and exposes StateFlow, composables collect it and trigger events through callbacks, ViewModel updates state in response.
Fragments & Lifecycle Management
Why should fragments use only default constructors?
Android system recreates fragments during configuration changes or process death using reflection calling the default constructor. If you add custom constructors with parameters, the system can’t recreate the fragment properly causing crashes. Pass data through arguments bundle using setArguments() which the system preserves across recreation. Factory pattern with companion object methods can create fragments with arguments while keeping default constructor.
Explain the fragment lifecycle and key methods.
Fragment lifecycle includes onAttach (attached to activity), onCreate (initialize non-UI), onCreateView (inflate layout), onViewCreated (view hierarchy exists), onStart (visible), onResume (interactive), onPause, onStop, onDestroyView (view hierarchy destroyed but fragment exists), onDestroy, onDetach. Views can be recreated multiple times while fragment instance persists, so clean up view references in onDestroyView to prevent leaks.
How do fragments communicate with each other?
Never directly reference other fragments. Use shared ViewModel scoped to the activity for fragment communication. Both fragments observe LiveData or StateFlow from the shared ViewModel. Alternatively, use Fragment Result API with setFragmentResultListener and setFragmentResult for one-time data passing. Navigation component supports SafeArgs for type-safe argument passing between destinations. Avoid coupling fragments through the activity as an intermediary.
Android Architecture & MVVM
Q: Explain the MVVM architecture pattern in Android.
MVVM separates UI (View), business logic (ViewModel), and data (Model). View observes ViewModel’s LiveData or StateFlow, ViewModel exposes UI state and handles events, Model manages data sources (repository pattern with local database and remote API). ViewModel survives configuration changes preventing data loss on rotation. This separation enables unit testing business logic without Android dependencies and keeps activities/fragments focused on UI rendering.
Q: What is the repository pattern and why use it?
Repository mediates between ViewModel and data sources (Room database, Retrofit API, SharedPreferences). It provides clean API to ViewModel abstracting data source complexity. Repository decides whether to fetch from network or return cached data, handles data synchronization, and converts between data layer models and domain models. This enables switching data sources without changing ViewModel and simplifies testing by mocking repositories.
Q: How does ViewModel survive configuration changes?
ViewModel is stored in ViewModelStore associated with activity or fragment’s lifecycle. During configuration changes, the system retains ViewModelStore while recreating the activity. New activity instance retrieves the same ViewModel from the retained ViewModelStore. ViewModel’s onCleared() calls only when the activity finishes permanently, not on rotation. This prevents data loss and eliminates need to save/restore complex state.
Q: Explain dependency injection with Hilt in Android.
Hilt provides compile-time dependency injection built on Dagger. Annotate application class with @HiltAndroidApp, activities with @AndroidEntryPoint, and define modules with @Module and @InstallIn. Hilt manages component lifecycles automatically creating scoped dependencies. Constructor injection uses @Inject, interface binding uses @Binds, and third-party types use @Provides. This eliminates manual dependency management and boilerplate while improving testability.
⚠️ Common mistake: Putting business logic in activities or fragments. I’ve seen production apps with 2000-line activities doing network calls, database operations, and complex calculations. Always extract business logic to ViewModel and data operations to repositories.
Android & Kotlin Challenges
20 Practice Questions
1. What does the suspend modifier do in Kotlin?
- Blocks the current thread
- Marks function as pausable in coroutines
- Runs function on background thread
- Delays function execution
2. Which coroutine builder returns a result?
- launch
- async (returns Deferred)
- runBlocking
- withContext
3. What survives configuration changes like rotation?
- Activity instance
- ViewModel
- Fragment instance
- View hierarchy
4. In Compose, what stores state across recomposition but not rotation?
- remember
- rememberSaveable
- mutableStateOf
- derivedStateOf
5. Which Flow type holds a single current value?
- Flow
- StateFlow
- SharedFlow
- ChannelFlow
6. Why must fragments use default constructors?
- Performance optimization
- System recreates with reflection using default constructor
- Required by Jetpack
- Prevents memory leaks
7. What handles side effects tied to composable lifecycle?
- LaunchedEffect
- remember
- SideEffect
- rememberCoroutineScope
8. Which pattern mediates between ViewModel and data sources?
- Factory pattern
- Singleton pattern
- Repository pattern
- Observer pattern
9. In val result = async { fetchData() }.await(), when does exception throw?
- At async call
- At await() call
- Never throws
- At coroutine scope
10. What prevents child coroutine failures from canceling siblings?
- CoroutineScope
- SupervisorScope
- GlobalScope
- ViewModelScope
11. Which Compose effect runs after successful recomposition?
- LaunchedEffect
- DisposableEffect
- SideEffect
- remember
12. How do fragments communicate without direct references?
- Through activity as intermediary
- Shared ViewModel or Fragment Result API
- Static variables
- Intent extras
13. What is Flow compared to LiveData?
- Flow is hot, LiveData is cold
- Flow is cold, LiveData is hot
- Both are hot
- Both are cold
14. When does ViewModel’s onCleared() call?
- On configuration change
- When activity finishes permanently
- On every rotation
- On app background
15. Which annotation marks an Android Application for Hilt?
- @AndroidEntryPoint
- @HiltAndroidApp
- @Module
- @Inject
16. What prevents recomposition when state derives from other state?
- remember
- derivedStateOf
- rememberSaveable
- mutableStateOf
17. Given launch { delay(100); println("A") }, what does delay() do?
- Blocks thread for 100ms
- Suspends coroutine for 100ms without blocking
- Cancels coroutine
- Creates new thread
18. Where should you clean up view references in fragments?
- onDestroy
- onDetach
- onDestroyView
- onPause
19. What is unidirectional data flow in MVVM?
- Data flows both ways
- State down, events up
- Everything in ViewModel
- Direct view manipulation
20. Which scope automatically cancels coroutines when ViewModel clears?
- GlobalScope
- lifecycleScope
- viewModelScope
- CoroutineScope
âť“ FAQ
đź”§ Should I learn Compose or stick with XML layouts?
Learn both. Compose is Android’s future and new projects should use it, but most existing codebases use XML. Understanding both makes you more valuable. Start with Compose for personal projects while knowing enough XML to maintain legacy code. Companies increasingly prefer candidates comfortable with Compose.
⚡ How important are Kotlin coroutines for Android interviews?
Critical. Coroutines replaced AsyncTask and are standard for asynchronous Android development. Expect questions on launch vs async, exception handling, Flow, and structured concurrency. Practice writing coroutine code, not just explaining concepts. Most Android roles test coroutine proficiency through coding challenges.
🏗️ Do I need to know Hilt or can I use manual dependency injection?
Hilt is becoming standard in Android development. While manual DI works for small apps, Hilt knowledge demonstrates understanding of modern Android architecture. Learn Hilt basics including modules, scopes, and injection. Understanding why DI matters is more important than Hilt syntax specifics.
📱 How much Java do Android developers need to know?
Minimal Java knowledge suffices since Kotlin is now standard. Understand Java interop for reading legacy code and using Java libraries. Focus energy on Kotlin features like coroutines, extension functions, and sealed classes rather than deep Java expertise. Most new Android code is Kotlin-first.
đź§Ş What testing frameworks should Android developers know?
Learn JUnit for unit tests, Espresso for UI tests, and MockK for mocking Kotlin code. Compose testing uses different APIs than View-based testing. Understand testing pyramid principles and when to use unit vs integration vs UI tests. Companies value developers who write testable code.
Final Thoughts
Mastering Android developer interview questions requires hands-on experience building apps with modern tools. The best preparation combines writing real Kotlin code using coroutines, creating Compose UIs, and implementing MVVM architecture in personal projects. Focus on understanding why Android architecture patterns exist, not just memorizing syntax.
Companies value Android developers who understand platform constraints, write maintainable code, and stay current with Jetpack libraries. Your preparation should include building complete apps demonstrating coroutine usage, Compose UI, proper architecture separation, and dependency injection rather than just reading documentation.
⚠️ Disclaimer: The interview strategies, sample answers, and negotiation tips provided in this guide are for educational purposes only. Hiring decisions are subjective and vary by company and industry. While these strategies are based on professional HR standards, they do not guarantee a specific job offer or result.








