Android interviews in 2026 focus on Jetpack Compose, Kotlin coroutines, and modern architecture. The old questions about XML layouts and AsyncTask are mostly gone.

This guide covers the 30 most common Android interview questions. Each answer is short and practical. Questions are grouped by difficulty level: Beginner, Intermediate, and Advanced.

Quick Reference — Modern Android Stack (2026)

ComponentOld WayModern Way (2026)
UIXML LayoutsJetpack Compose
NavigationFragment transactionsNavigation Compose
State managementLiveDataStateFlow + Compose State
Async workAsyncTask / RxJavaKotlin Coroutines + Flow
DIDagger 2Hilt / Koin
DatabaseSQLite / CursorRoom
NetworkingVolleyRetrofit / Ktor
Image loadingPicassoCoil
ArchitectureMVC / MVPMVVM / MVI

Beginner Questions (1-10)

1. What are the four main Android components?

The four main components are Activity (screens), Service (background work), BroadcastReceiver (system events), and ContentProvider (shared data). Each component has its own lifecycle. They are declared in the AndroidManifest.xml file.

2. What is the Activity lifecycle?

An Activity goes through these states: onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy(). The most important are onCreate() for setup, onResume() for becoming visible and interactive, and onDestroy() for cleanup.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp()
        }
    }
}

3. What is Jetpack Compose?

Jetpack Compose is Android’s modern UI toolkit. It uses a declarative approach — you describe what the UI should look like, and the framework handles updates. It replaces XML layouts. Composable functions are the building blocks.

@Composable
fun Greeting(name: String) {
    Text(text = "Hello, $name!")
}

4. What is the difference between state and remember in Compose?

state holds a value that triggers recomposition when it changes. remember preserves a value across recompositions. Use remember { mutableStateOf() } to create state that survives recomposition but not configuration changes.

@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    Button(onClick = { count++ }) {
        Text("Count: $count")
    }
}

5. What is ViewModel?

ViewModel stores and manages UI-related data. It survives configuration changes like screen rotation. It should not hold references to Activities or Views. Use it with StateFlow to expose UI state to Compose.

class UserViewModel : ViewModel() {
    private val _users = MutableStateFlow<List<User>>(emptyList())
    val users: StateFlow<List<User>> = _users.asStateFlow()

    fun loadUsers() {
        viewModelScope.launch {
            _users.value = repository.getUsers()
        }
    }
}

6. What is the difference between implicit and explicit intents?

Explicit intents specify the exact component to start (e.g., a specific Activity). Implicit intents declare an action and let the system find a matching component. Use explicit intents within your app and implicit intents for system actions like sharing or opening a URL.

// Explicit — start a specific activity
val intent = Intent(context, DetailActivity::class.java)

// Implicit — open a URL in any browser
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com"))

7. What is a Fragment?

A Fragment is a reusable portion of the UI. It has its own lifecycle tied to its host Activity. Fragments have their own back stack, saved state, and lifecycle callbacks. In modern Android (2026), Compose navigation has mostly replaced Fragment-based navigation. However, many large apps still use Fragments for backward compatibility. If you work with Fragments, use viewLifecycleOwner for UI-related observations.

8. What is the AndroidManifest.xml?

The manifest declares your app’s components, permissions, hardware features, and minimum SDK version. Every Activity, Service, BroadcastReceiver, and ContentProvider must be registered here. The system reads it before running your app.

9. What is Gradle in Android?

Gradle is the build system for Android projects. It compiles code, manages dependencies, and creates APK/AAB files. Android uses Kotlin DSL (build.gradle.kts) or Groovy DSL (build.gradle) for build configuration. In 2026, Kotlin DSL is the standard. Version catalogs (libs.versions.toml) manage dependency versions centrally. Build variants let you create debug and release builds with different configurations.

10. What is the difference between dp, sp, and px?

dp (density-independent pixels) scales with screen density for consistent sizing. sp (scale-independent pixels) also scales with the user’s font size preference. px is raw pixels — avoid using it. Always use dp for dimensions and sp for text sizes.


Intermediate Questions (11-22)

11. What is recomposition in Jetpack Compose?

Recomposition is when Compose re-executes composable functions because their inputs changed. Only the composables that read the changed state are re-executed, not the entire UI tree. This makes Compose efficient by default. Compose skips recomposition for composables whose inputs have not changed. To help the compiler, use stable types (primitives, strings, data classes with immutable fields) as parameters.

12. What is LaunchedEffect?

LaunchedEffect runs a suspend function when a composable enters the composition or when its key changes. It is used for side effects like loading data, starting animations, or observing events. The coroutine is cancelled when the composable leaves the composition.

@Composable
fun UserScreen(userId: String) {
    LaunchedEffect(userId) {
        viewModel.loadUser(userId)  // runs when userId changes
    }
}

13. What is the difference between rememberSaveable and remember?

remember preserves state across recompositions only. rememberSaveable also preserves state across configuration changes (like rotation) and process death. Use rememberSaveable for user input like text fields.

var text by rememberSaveable { mutableStateOf("") }
TextField(value = text, onValueChange = { text = it })

14. What is Hilt and why use it?

Hilt is Google’s dependency injection library for Android, built on Dagger. It automatically manages the lifecycle of dependencies. It provides predefined scopes like @Singleton, @ViewModelScoped, and @ActivityScoped. It reduces boilerplate compared to manual DI.

@HiltViewModel
class UserViewModel @Inject constructor(
    private val repository: UserRepository
) : ViewModel()

15. What is Room database?

Room is a SQLite abstraction layer from Jetpack. It provides compile-time SQL verification, automatic mapping to Kotlin objects, and Flow/coroutine support. It has three main components: Entity (table), DAO (queries), and Database (connection).

@Entity
data class User(
    @PrimaryKey val id: Int,
    val name: String
)

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): Flow<List<User>>
}

16. What is WorkManager?

WorkManager handles deferrable, guaranteed background work. It survives app restarts and device reboots. Use it for tasks like syncing data, uploading logs, or periodic cleanup. It respects battery optimization constraints. You can chain work, add constraints (like requiring WiFi), and observe progress.

val uploadWork = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
    )
    .build()

WorkManager.getInstance(context).enqueue(uploadWork)

17. How do you handle configuration changes?

Configuration changes (like rotation, locale change, dark mode toggle) destroy and recreate the Activity. Use ViewModel to survive configuration changes — it lives longer than the Activity. Use rememberSaveable in Compose for UI state like text input. For complex state, use SavedStateHandle in your ViewModel. Avoid storing UI data directly in the Activity.

class SearchViewModel(
    private val savedState: SavedStateHandle
) : ViewModel() {
    val query = savedState.getStateFlow("query", "")

    fun updateQuery(newQuery: String) {
        savedState["query"] = newQuery
    }
}

18. What is the Navigation component in Compose?

Navigation Compose provides a declarative way to handle navigation. You define a NavHost with routes and use NavController to navigate. It supports arguments, deep links, and back stack management.

NavHost(navController, startDestination = "home") {
    composable("home") { HomeScreen(navController) }
    composable("detail/{id}") { backStackEntry ->
        DetailScreen(id = backStackEntry.arguments?.getString("id"))
    }
}

19. What is ProGuard/R8?

R8 is Android’s code shrinker and optimizer (it replaced ProGuard). It removes unused code (tree shaking), renames classes to short names (obfuscation), and optimizes bytecode. This makes your APK smaller and harder to reverse-engineer. You configure keep rules in proguard-rules.pro. Enable it in your release build with isMinifyEnabled = true. Always test your release build because R8 can break reflection-based libraries.

20. What is the difference between Serializable and Parcelable?

Both send objects between components. Serializable is Java’s built-in mechanism — easy but slow (uses reflection). Parcelable is Android-specific — faster but requires more code. Use @Parcelize from Kotlin parcelize plugin for the best of both.

@Parcelize
data class User(val name: String, val age: Int) : Parcelable

21. What are Kotlin coroutine dispatchers?

Dispatchers determine which thread a coroutine runs on. Dispatchers.Main runs on the main/UI thread. Dispatchers.IO is for network and disk operations. Dispatchers.Default is for CPU-intensive work. Never do heavy work on Main.

viewModelScope.launch(Dispatchers.IO) {
    val data = repository.fetchFromNetwork()
    withContext(Dispatchers.Main) {
        updateUI(data)
    }
}

22. What is MVVM architecture?

MVVM stands for Model-View-ViewModel. The Model is your data layer (repositories, databases, APIs). The View is the UI (Composables or Activities). The ViewModel connects them and holds UI state. Data flows one way: Model to ViewModel to View. The View observes state from the ViewModel using StateFlow. User actions go from View to ViewModel as function calls.

// ViewModel exposes state
class UserViewModel(private val repo: UserRepository) : ViewModel() {
    private val _state = MutableStateFlow(UserUiState())
    val state: StateFlow<UserUiState> = _state.asStateFlow()

    fun loadUsers() {
        viewModelScope.launch {
            _state.update { it.copy(loading = true) }
            val users = repo.getUsers()
            _state.update { it.copy(users = users, loading = false) }
        }
    }
}

// View observes state
@Composable
fun UserScreen(viewModel: UserViewModel) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    if (state.loading) CircularProgressIndicator()
    else LazyColumn { items(state.users) { UserItem(it) } }
}

Advanced Questions (23-30)

23. What is Compose Multiplatform?

Compose Multiplatform lets you share Jetpack Compose UI code across Android, iOS, desktop, and web. It is built on Kotlin Multiplatform (KMP). You write shared UI in common code and platform-specific features with expect/actual. The Android version uses Jetpack Compose directly, while iOS uses a Skia-based renderer. Many companies adopt it to share up to 90% of code between platforms. Learn more in our KMP tutorial series.

24. What is MVI architecture?

MVI stands for Model-View-Intent. The user triggers Intents (actions). These go through a reducer that produces a new Model (state). The View renders the state. State is always immutable and flows in one direction. This makes the UI predictable, testable, and easy to debug. MVI is becoming more popular than MVVM in 2026 because it handles complex state better. Time-travel debugging is possible because every state change is explicit.

// State
data class UiState(val items: List<Item> = emptyList(), val loading: Boolean = false)

// Intent
sealed class UiAction {
    data object LoadItems : UiAction()
    data class DeleteItem(val id: Int) : UiAction()
}

25. How do you optimize Compose performance?

Key strategies: use key() in LazyColumn to help Compose identify items. Use derivedStateOf to avoid unnecessary recompositions. Use Stable or Immutable annotations on data classes. Avoid allocating objects inside composable functions. Profile with Layout Inspector.

val filteredItems by remember(items, query) {
    derivedStateOf {
        items.filter { it.name.contains(query) }
    }
}

26. What is Baseline Profile?

Baseline Profiles tell the ART compiler which code paths to pre-compile at install time. This improves app startup time by 30-40%. You generate them with the Macrobenchmark library. Google Play uses them to optimize delivery. Every production app should have Baseline Profiles.

// Generate baseline profile with Macrobenchmark
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
    @get:Rule
    val rule = BaselineProfileRule()

    @Test
    fun generateProfile() {
        rule.collect(packageName = "com.kemalcodes.app") {
            startActivityAndWait()
            // Navigate through critical user flows
            device.findObject(By.text("Home")).click()
        }
    }
}

Deep links open specific screens in your app from external sources (web, notifications). Declare intent filters in the manifest and handle them in Navigation Compose. Use navDeepLink to map URLs to composable destinations.

composable(
    route = "profile/{userId}",
    deepLinks = listOf(navDeepLink {
        uriPattern = "https://example.com/profile/{userId}"
    })
) { backStackEntry ->
    ProfileScreen(userId = backStackEntry.arguments?.getString("userId"))
}

28. What is the difference between cold and hot flows?

Cold flows start emitting only when collected. Each collector gets its own emission. flow { } creates cold flows. Hot flows emit regardless of collectors. StateFlow and SharedFlow are hot. Hot flows are used for shared state in ViewModels. In Compose, collect flows with collectAsStateWithLifecycle() to respect the lifecycle.

// Cold flow — each collector triggers new emission
fun fetchUsers(): Flow<List<User>> = flow {
    val users = api.getUsers()
    emit(users)
}

// Hot flow — shared state, emits regardless of collectors
private val _users = MutableStateFlow<List<User>>(emptyList())
val users: StateFlow<List<User>> = _users.asStateFlow()

29. How do you test Compose UI?

Use ComposeTestRule to test composable functions. Find elements with onNodeWithText() or onNodeWithTag(). Perform actions with performClick(). Assert with assertIsDisplayed(). Use semantic test tags for reliable element selection.

@Test
fun counterIncrements() {
    composeTestRule.setContent { Counter() }
    composeTestRule.onNodeWithText("Count: 0").assertIsDisplayed()
    composeTestRule.onNodeWithText("Count: 0").performClick()
    composeTestRule.onNodeWithText("Count: 1").assertIsDisplayed()
}

30. What is App Startup and how do you optimize it?

App Startup library initializes components efficiently at app launch. It merges multiple content providers into one, reducing startup overhead. To optimize startup time: minimize work in Application.onCreate(), use lazy initialization, enable Baseline Profiles, defer non-critical work with WorkManager, and avoid disk/network I/O on the main thread. Use reportFullyDrawn() to measure actual time to interactive. Target under 500ms for cold start. Profile with Android Studio’s System Trace to find bottlenecks.


Bonus Tips for Interviews

  1. Know Jetpack Compose deeply — Most Android interviews in 2026 focus on Compose. Understand recomposition, state hoisting, side effects, and performance. Practice with our Jetpack Compose tutorial.

  2. Understand architecture patterns — Be ready to explain MVVM and MVI with real examples. Draw the data flow diagram if asked.

  3. Practice coroutines — Write code that uses viewModelScope, handles errors, and switches dispatchers. Know the difference between launch and async.

  4. Show production experience — Talk about how you handled real problems: memory leaks, ANRs, crash reporting, CI/CD, and testing strategies.

  5. Know the Android lifecycle — Despite Compose, the Activity and ViewModel lifecycles still matter. Understand when state is lost and how to preserve it.

  6. Learn Kotlin Multiplatform — KMP is growing fast in 2026. Being familiar with it is a strong differentiator. Check our KMP vs Flutter vs React Native comparison.

  7. Review your past projects — Be ready to explain architecture decisions, trade-offs, and what you would do differently.

  8. Prepare system design questions — Senior roles ask about offline-first architecture, caching strategies, modularization, and CI/CD pipelines. Be ready to design a feature end-to-end: from API to database to UI.