Friday, May 30, 2025

Android Kotlin Interview Questions for Intermediate level part 1

 Here are Interview Questions for the Intermediate level 1-3 yrs of Experience level. Get ready for in-depth discussion during a face-to-face interview:



1. What is the Android Architecture?

Answer:

Android architecture is a layered software stack that enables app developers to create applications that run on the Android OS. It’s designed to abstract hardware complexities and provide a flexible framework.

  • Linux Kernel: The foundation providing core system services like security, memory management, process management, and hardware abstraction (e.g., drivers for camera, WiFi).
  • Libraries & Android Runtime (ART): Contains native libraries written in C/C++ like SQLite for database management, OpenGL ES for graphics, and WebKit for web rendering. ART replaces the older Dalvik VM and improves performance by compiling apps ahead of time.
  • Application Framework: Provides Java/Kotlin APIs such as ActivityManager (manages activities), WindowManager (handles UI windows), Content Providers (manage data sharing), and NotificationManager.
  • Applications: This is the topmost layer where pre-installed apps like Phone, Contacts, and your own user apps run.

Example: When your app sends a notification, it requests the NotificationManager (application framework), which interfaces with system services via the Linux kernel to display the notification on screen.


2. What is the difference between Activity, Fragment, and View?

Answer:

  • Activity: Represents a full screen or window in an app. It is the entry point for interacting with the user. Activities have their own lifecycle and manage the UI components inside them. They also act as containers for fragments.
  • Fragment: Represents a reusable portion or modular section of UI within an activity. It has its own lifecycle but depends on the parent activity’s lifecycle. Fragments allow for more dynamic and flexible UI designs, such as tabbed interfaces or multi-pane layouts on tablets.
  • View: The smallest building block of UI components like buttons, text fields, images, etc. Views do not have their own lifecycle; they are rendered inside activities or fragments.

Example: In a messaging app, the main activity might host two fragments — one showing a list of conversations and another displaying the chat. Each item in the list is a View.


3. Explain the Activity Lifecycle with a real-world use case.

Answer:

An Activity goes through several lifecycle states:

  • onCreate() — Called when the activity is first created. Initialize UI components here.
  • onStart() — Called when the activity is becoming visible.
  • onResume() — Called when the activity starts interacting with the user.
  • onPause() — Called when the system is about to put the activity into the background.
  • onStop() — Called when the activity is no longer visible.
  • onRestart() — Called after the activity has been stopped, just before it starts again.
  • onDestroy() — Called before the activity is destroyed.

Use Case: In an expense tracking app, when a user switches away (onPause), you might save draft data or pause sensor updates. When the user returns (onResume), you refresh the UI and data. onSaveInstanceState() can be used to save UI state during rotation.


4. What is ViewModel and why is it useful?

Answer:

ViewModel is an architecture component designed to store and manage UI-related data in a lifecycle-conscious way. It survives configuration changes such as device rotations, which destroy and recreate activities.

Why use ViewModel?

  • It separates UI data from UI controllers (Activities/Fragments), making code cleaner.
  • Avoids expensive re-fetching of data on rotation.
  • Integrates well with LiveData for reactive UI updates.

Example: In a weather app, you fetch the current weather in ViewModel. When the device rotates, the ViewModel persists, so your app doesn’t make redundant network calls.


5. What is LiveData and how does it work with ViewModel?

Answer:

LiveData is a lifecycle-aware observable data holder. It respects the lifecycle state of UI components and only updates observers when they are active.

  • Prevents memory leaks by automatically cleaning up observers.
  • Ensures UI updates happen only when the Activity/Fragment is in a valid state.
  • Simplifies asynchronous UI updates.

Example: A stock price LiveData in ViewModel updates the UI automatically when the data changes. Observers in the Activity subscribe using observe() and get notified without manual lifecycle handling.


6. What is the difference between LiveData and StateFlow?

Answer:

Both are observable data holders but differ in origin and features:

  • LiveData: Lifecycle-aware, built for Android, updates observers only when UI is active, easy to integrate with ViewModel and DataBinding.
  • StateFlow: Part of Kotlin Coroutines, always holds a current value, requires manual lifecycle management with repeatOnLifecycle or similar, better for complex data streams.

Use LiveData if you want simple lifecycle awareness; use StateFlow for advanced asynchronous flows with coroutines.


7. How do you handle configuration changes in Android?

Answer:

Configuration changes (e.g., rotation, locale changes) restart the activity by default, which can cause data loss.

  • Use ViewModel to retain data across config changes.
  • Use onSaveInstanceState() to save small UI state like scroll position.
  • Avoid android:configChanges in manifest unless necessary (it prevents recreation but can cause issues).
  • For complex cases, use retained fragments or saved state modules.

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

Answer:

  • Explicit Intent: Specifies the exact component to start by name (class). Used for internal app communication.
  • Implicit Intent: Specifies an action to perform, letting Android find suitable apps. Used for system-wide actions like sharing or opening URLs.

Example:
Explicit — Intent(this, DetailActivity::class.java)
Implicit — Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com"))


9. How does data persistence work in Android?

Answer:

Android provides various ways to persist data:

  • SharedPreferences: Store key-value pairs for small data like user settings.
  • SQLite/Room: Structured relational database for complex, large datasets.
  • Files: Store binary/text files like images or logs.
  • DataStore: Modern replacement for SharedPreferences, based on Kotlin Coroutines and Flow, providing asynchronous and consistent data storage.

Choose the method based on data size, structure, and access pattern.


10. What is Room Database and how is it different from SQLite?

Answer:

Room is a wrapper over SQLite designed to simplify database access and improve maintainability.

  • Provides compile-time checks for SQL queries.
  • Reduces boilerplate code by generating much of the SQLite interaction.
  • Supports observable queries with LiveData or Flow.
  • Components:
    • @Entity: Defines database tables.
    • @Dao: Data Access Object, defines SQL queries.
    • @Database: Connects entities and DAOs.

Room helps avoid common SQLite pitfalls like runtime errors and tedious cursor management.


11. What is Coroutine and why is it used in Android?

Answer:

Coroutines are Kotlin’s way of handling asynchronous programming and concurrency with a simple and efficient API. Unlike traditional threads, coroutines are lightweight and can be suspended and resumed without blocking the main thread.

  • Why use Coroutines?
    • Avoids blocking the main (UI) thread during long operations such as network calls, file I/O, or database access.
    • More efficient and less resource-intensive compared to Java threads.
    • Structured concurrency: coroutines can be scoped and managed, reducing memory leaks and uncontrolled execution.
    • Supports cancellation and timeout out-of-the-box.

Example:

kotlin

CopyEdit

viewModelScope.launch {

    val data = repository.getDataFromNetwork()

    _uiState.value = data

}

Here, viewModelScope ensures the coroutine is canceled if the ViewModel is destroyed, preventing memory leaks.


12. What is the difference between suspend functions and regular functions?

Answer:

  • Regular functions execute synchronously and run to completion once called.
  • Suspend functions are marked with the suspend modifier and can suspend execution without blocking the current thread.
  • Suspend functions can only be called from other suspend functions or coroutines.
  • They are designed to run long-running operations asynchronously but allow easy, sequential style code.

Example:

kotlin

CopyEdit

suspend fun fetchUser(): User {

    return api.getUserData()

}

This can be called inside a coroutine, and it suspends while waiting for the network response.


13. What is MVVM architecture in Android?

Answer:

MVVM (Model-View-ViewModel) is a design pattern that separates concerns and improves maintainability:

  • Model: Data layer that represents your business logic and data sources (local DB, network, etc.).
  • ViewModel: Acts as a bridge between the Model and View, holding UI data and handling business logic for the UI. It survives configuration changes.
  • View: The UI layer (Activity/Fragment) that observes the ViewModel and updates the UI reactively.

Benefits:

  • Cleaner, testable, and maintainable code.
  • UI logic separated from business/data logic.
  • Works well with LiveData or StateFlow for reactive programming.

14. How do you handle API errors in Android?

Answer:

Handling API errors gracefully is critical for good UX:

  • Use try-catch blocks around API calls or use Retrofit’s error handling.
  • Implement a sealed class or wrapper for different states such as:
    • Success (with data),
    • Loading (for progress indicators),
    • Error (with exception details).
  • Show user-friendly messages based on error type (network error, timeout, server error).
  • Implement retry logic or fallback data.

Example sealed class:

kotlin

CopyEdit

sealed class Result<out T> {

    data class Success<T>(val data: T): Result<T>()

    data class Error(val exception: Throwable): Result<Nothing>()

    object Loading: Result<Nothing>()

}


15. What is Hilt and how does it help with dependency injection?

Answer:

Hilt is a dependency injection (DI) library for Android built on top of Dagger, designed to simplify DI setup and usage.

  • Automates the generation of DI code.
  • Provides predefined components tied to Android lifecycle (Application, Activity, Fragment).
  • Integrates with Jetpack components like ViewModel, WorkManager, Navigation.
  • Reduces boilerplate compared to manual Dagger setup.
  • Improves app modularity, testing, and code readability.

Example:

  • Annotate the Application class with @HiltAndroidApp.
  • Annotate Activities/Fragments with @AndroidEntryPoint.
  • Inject dependencies using @Inject in constructors.

16. What are sealed classes in Kotlin and how are they useful in Android?

Answer:

Sealed classes are a special kind of class that restricts the hierarchy to a fixed set of subclasses, all known at compile time.

  • Useful for representing restricted types with a fixed number of possible states.
  • Ideal for modeling state machines, result wrappers (success, error, loading).
  • The compiler knows all subclasses, enabling exhaustive when statements without needing an else branch.

Example:

kotlin

CopyEdit

sealed class NetworkResult<out T> {

    object Loading: NetworkResult<Nothing>()

    data class Success<T>(val data: T): NetworkResult<T>()

    data class Error(val exception: Throwable): NetworkResult<Nothing>()

}


17. Explain how WorkManager works and when to use it.

Answer:

WorkManager is a Jetpack library for managing deferrable, guaranteed background work, even if the app exits or the device restarts.

  • Supports constraints like network availability or charging status.
  • Work requests can be chained or combined.
  • Ensures tasks are executed reliably using JobScheduler, AlarmManager, or Firebase JobDispatcher under the hood depending on API level.
  • Works well for periodic or one-time background tasks such as syncing data, uploading logs, or processing images.

Example:

kotlin

CopyEdit

val workRequest = OneTimeWorkRequestBuilder<MyWorker>().build()

WorkManager.getInstance(context).enqueue(workRequest)


18. How do you optimize Android app performance?

Answer:

Common optimization strategies:

  • Avoid heavy operations on the main thread.
  • Use efficient data structures and algorithms.
  • Optimize layouts by reducing nested views or using ConstraintLayout.
  • Use RecyclerView for long lists with ViewHolder pattern.
  • Use caching and pagination for network data.
  • Avoid memory leaks by managing references properly.
  • Use profiling tools (Android Profiler, LeakCanary) to monitor CPU, memory, and network.
  • Optimize images by using proper formats and sizes.
  • Use ProGuard or R8 for code shrinking and obfuscation.

19. What is the difference between Parcelable and Serializable in Android?

Answer:

Both are interfaces to serialize objects for passing between activities or saving state, but:

  • Parcelable: Android-specific, faster, more efficient as it requires manual implementation of serialization logic. Recommended for Android.
  • Serializable: Java standard, slower due to reflection and generates more garbage, easier to implement (marker interface).

Use Parcelable for performance-critical Android apps, especially when passing large data via Intent extras.


20. How do you secure data in Android apps?

Answer:

Important practices include:

  • Use Android Keystore System to store cryptographic keys securely.
  • Use EncryptedSharedPreferences and EncryptedFile to store sensitive data.
  • Avoid storing sensitive data in plaintext or on external storage.
  • Use HTTPS with SSL/TLS for network communication.
  • Minimize permissions to only what your app requires.
  • Obfuscate code using ProGuard/R8.
  • Use user authentication and biometrics APIs.
  • Validate all inputs to prevent injection attacks.



21. What is Android Jetpack and what are its components?

Answer:

Android Jetpack is a set of libraries, tools, and architectural guidance provided by Google to help developers write high-quality, maintainable apps easily.

Key Components:

  • Architecture Components: ViewModel, LiveData, Room, WorkManager — help manage lifecycle, data persistence, background work.
  • UI Components: Navigation (handles app navigation and deep linking), Paging (loads data gradually), Animation.
  • Behavior Components: Notifications, Permissions, Sharing.
  • Foundation Components: AppCompat (backward compatibility), Multidex, Test.

Jetpack simplifies common development tasks and encourages best practices with reactive and lifecycle-aware components.


22. How does Room handle database migrations?

Answer:

Room supports schema migrations when you change your database schema (e.g., add/remove columns or tables).

  • You provide a Migration object defining how to convert the old schema to the new one using SQL statements.
  • Room runs this migration when the database version is incremented.
  • If you don’t provide migrations, Room throws a IllegalStateException on version mismatch.
  • You can fallback to destructive migration (fallbackToDestructiveMigration()) which deletes the database but is not recommended for production.

Example:

kotlin

CopyEdit

val MIGRATION_1_2 = object : Migration(1, 2) {

  override fun migrate(database: SupportSQLiteDatabase) {

    database.execSQL("ALTER TABLE users ADD COLUMN last_update INTEGER")

  }

}


23. What are Broadcast Receivers and how are they used?

Answer:

Broadcast Receivers listen for system-wide or app-wide broadcast messages (Intents) and react accordingly.

  • They handle asynchronous events like battery low, connectivity changes, or custom app events.
  • Can be registered statically in AndroidManifest.xml or dynamically in code.
  • Use onReceive() callback to handle the event.
  • Limited execution time (about 10 seconds) in onReceive().

Example: Listening for network connectivity changes to update UI or retry operations.


24. Explain the difference between Service, IntentService, and JobIntentService.

Answer:

  • Service: Runs in the background to perform long-running operations without user interaction. Runs on the main thread, so developers must manage threading manually.
  • IntentService (deprecated): A subclass of Service that handles asynchronous requests on a worker thread and stops itself when done. Good for short tasks.
  • JobIntentService: Supports background execution compatible with newer Android versions with restrictions on background services. It queues work and executes it on a background thread respecting OS constraints.

25. What is the difference between apply() and commit() in SharedPreferences?

Answer:

  • commit(): Synchronously writes changes to disk and returns a boolean indicating success. Blocks the calling thread.
  • apply(): Asynchronously writes changes and returns immediately. Changes are persisted in the background. No success status.

Best Practice: Use apply() for non-critical settings to avoid blocking the UI thread.


No comments:

Post a Comment

Top 30 interview questions

Android Development Interview Q&A (5+ Years Experience) Android Development Fundamentals Q: What are the main Android app components and...