1 / 12

Android & Kotlin

Interview Questions & Answers

Android Development Kotlin Programming

Android What is Android?

Android is an open-source, Linux-based operating system designed primarily for mobile devices such as smartphones and tablets.

  • Developed by Google
  • Provides a rich application framework
  • Supports development in Java and Kotlin
  • Used on billions of devices worldwide

Android Android Architecture Components

Application Layer
Application Framework
Native Libraries
Android Runtime
Linux Kernel
  1. Application: User apps (Contacts, WhatsApp)
  2. Application Framework: Activity Manager, Location Manager
  3. Native Libraries: OpenGL, Media, SQLite
  4. Android Runtime: Dalvik Virtual Machine (DVM)
  5. Linux Kernel: WiFi, Camera, Audio drivers

Android Activity Launch Modes

1. Standard (Default)

A new instance of the activity is created and pushed onto the back stack every time it's launched.

2. SingleTop

If an instance of the activity is already at the top of the back stack, a new instance isn't created.

Instead, the system reuses the existing instance and calls its onNewIntent() method with the new intent

3. SingleTask

This launch mode ensures that there is only one instance of the activity in a task. If an instance of the activity already exists anywhere in the back stack, the system doesn't create a new instance

4. SingleInstance

This is the most restrictive launch mode. It's similar to singleTask, but the activity is launched in its own, new task and is the only activity allowed in that task

What are the Android Core Android Components

🎯 Activity

: Represents a single screen with a user interface. It's what the user interacts with. An app can have multiple activities, and each has its own lifecycle

βš™οΈ Service

A component that runs in the background to perform long-running operations, like playing music or fetching data from a network, without a user interface

πŸ“‘ Broadcast Receiver

A component that responds to system-wide broadcast announcements (or Intents). An example is a receiver that listens for a "low battery" broadcast to save data

πŸ’Ύ Content Provider

Manages access to a structured set of data. It's a standardized way to share data between applications. For instance, the Contacts app uses a content provider to share contact information with other apps

What is Android Intent and Types

Intent is a messaging object used to request an action from another app component.

Explicit Intent

Specifies the component to be started by name.

val intent = Intent(this, ActivityTwo::class.java)
intent.putExtra("Value1", "This is ActivityTwo")
intent.putExtra("Value2", "This Value two for ActivityTwo")
startActivity(intent)
            

Implicit Intent

Specifies the action to be performed and allows the Android system to find the best component to handle it

val i = Intent(Intent.ACTION_VIEW, 
    Uri.parse("http://www.interviewbit.com"))
startActivity(i)

Android Activity Lifecycle

onCreate()
onStart()
onResume()
onPause()
onStop()
onDestroy()
onRestart()
  • onCreate(): The activity is being created. This is where you typically perform all of your static setup, like calling setContentView() to define the UI and initializing variables
  • onStart(): The activity is about to become visible to the user
  • onResume(): The activity is visible and has the user's focus. This is the state where the user can interact with the app
  • onPause(): The activity is losing user focus. Another activity (e.g., a semi-transparent dialog) is about to come to the foreground. You should save any unsaved data in this state
  • onStop(): The activity is no longer visible to the user. This can happen if another activity covers it completely
  • onDestroy(): The activity is being destroyed. This can be because the user is dismissing it, or the system is killing it to free up resources
  • onRestart(): The activity has been stopped and is now being brought back to the foreground

Android Fragment Lifecycle

onAttach()
onCreate()
onCreateView()
onViewCreated()
onActivityCreated()
onStart()
onResume()
onPause()
onStop()
onDestroyView()
onDestroy()
onDetach()
  • onAttach(): The fragment is attached to its host activity.
  • onCreate(): The fragment is being created. This is a good place for initialization.
  • onCreateView(): The fragment's UI is being drawn. You must return a View from this method.
  • onViewCreated(): The View has been created, and you can now set up its listeners or retrieve references to its components.
  • onActivityCreated(): The fragment's host activity has been created. You can access the activity's views and resources here.
  • onStart(): The fragment is about to become visible.
  • onResume(): The fragment is visible and has the user's focus.
  • onPause(): The fragment is losing focus.
  • onStop(): The fragment is no longer visible.
  • onDestroyView(): The view hierarchy associated with the fragment is being removed.
  • onDestroy(): The fragment is being destroyed.
  • onDetach(): The fragment is detached from its host activity

Key Differences from Activity:

  • Host Dependency: A fragment's lifecycle is completely dependent on its host activity's lifecycle. A fragment cannot exist on its own
  • Modularity: Fragments are reusable components that can be used to create flexible UIs, especially for tablets and multi-pane layouts
  • Creation:An activity uses setContentView() to set its layout, while a fragment uses onCreateView() to inflate its layout

Android Types of Services

In Android, a Service is an application component that can perform long-running operations in the background, without a user interface. Services are primarily used for tasks that shouldn't be interrupted by the user navigating away from an activity, such as playing music, fetching data from a network, or monitoring a user's location

There are three main types of services in Android, each with a different purpose and set of behaviors

πŸ”” Foreground Service

A foreground service performs a task that is noticeable to the user. It must display a persistent notification in the status bar while it's running

πŸ”‡ Background Service

A background service performs tasks that are not directly noticeable to the user. These services run without a notification. With modern Android versions (Android 8.0 and higher), background services have strict limitations to conserve battery and system resources. They are generally only used for short, non-critical tasks. For longer background tasks, Android now recommends using WorkManager or JobScheduler

πŸ”— Bound Service

A bound service provides a client-server interface that allows other components (like activities) to bind to it and interact with it. A bound service runs only as long as another application component is bound to it. Once all clients unbind, the service is destroyed

Note: For longer background tasks, Android recommends using WorkManager or JobScheduler.

Android MVVM Architecture

Model-View-ViewModel - Separates UI from business logic

Model
ViewModel
View

πŸ“Š Model

Application's data and business logic. Independent of UI.

🎯 View

UI layer (Activity/Fragment). Displays data and forwards user interactions.

πŸ”„ ViewModel

Intermediary between Model and View. Holds presentation logic and exposes data through observables.

Data Flow:

View β†’ ViewModel β†’ Model β†’ ViewModel β†’ View (automatic UI updates)

Android Other Architecture Patterns

MVC (Model-View-Controller)

  • Model: Data and business logic
  • View: UI (Activity/Fragment)
  • Controller: Mediator (Activity acts as both View and Controller)

Issue: Can lead to "God Activity" problem

MVP (Model-View-Presenter)

  • Model: Same as MVC
  • View: Passive interface
  • Presenter: Contains business logic, plain Java/Kotlin class

Advantage: Better testability

Android LiveData

LiveData is an observable data holder class that is lifecycle-aware.

Why use LiveData?

  • 🚫 No Memory Leaks: Observers bound to LifecycleOwner objects, automatically removed when destroyed
  • πŸ”„ UI Always Up-to-Date: Notifies observers of data changes, automatic UI updates
  • ⏸️ Lifecycle Aware: Only updates active components (STARTED or RESUMED)
  • πŸ“± Configuration Changes: Data survives screen rotations

Android ViewModel

A class designed to store and manage UI-related data in a lifecycle-conscious way.

Why use ViewModel?

  • πŸ”„ Survives Configuration Changes: Data persists through screen rotations
  • 🎯 Separation of Concerns: Separates UI logic from business logic
  • πŸ§ͺ Testability: No dependency on UI, can be unit-tested without Android framework
  • πŸ“Š Data Management: Single source of truth for UI data

Key Point: ViewModel instances are not destroyed during configuration changes, avoiding data loss and unnecessary network/database calls.

Android Clean Architecture

Presentation Layer
Domain Layer
Data Layer

🎨 Presentation Layer (UI)

Activities, Fragments, Views, ViewModels - Everything user sees

πŸ’Ό Domain Layer (Core)

Pure Kotlin/Java - No Android dependencies

  • Entities: Core business objects
  • Use Cases: Application-specific business logic

πŸ’Ύ Data Layer (Implementation)

Repositories, APIs, Databases - Data handling

  • Repository Interface: Defined in Domain Layer
  • Repository Implementation: Concrete implementation

Kotlin

Modern Programming Language for JVM

Kotlin val vs var

Feature val var
Mutability Read-only (immutable) Mutable
Assignment Cannot be reassigned Can be reassigned
Java Equivalent final keyword Regular variable
val name = "Kotlin"  // Cannot be changed
var age = 25         // Can be changed

// name = "Java"     // Compilation error
age = 26             // Valid

Kotlin Null Safety

Feature that helps eliminate NullPointerException at compile time.

Key Concepts:

  • Non-nullable types: Variables cannot hold null by default
  • Nullable types: Add ? after type to allow null
  • Safe Call Operator (?.): Access method/property on nullable object
  • Elvis Operator (?:): Provide default value for nullable expression
  • Not-null assertion (!!): Convert nullable to non-null (use with caution)
var name: String = "Kotlin"    // Non-nullable
var nullableName: String? = null  // Nullable

val length = nullableName?.length ?: 0  // Safe call + Elvis

Kotlin Data Classes

Special class designed to hold data. Compiler automatically generates useful methods.

Auto-generated methods:

  • equals(): Compares objects based on properties
  • hashCode(): Generates hash code for the object
  • toString(): String representation including properties
  • copy(): Creates copy, optionally modifying some properties
data class User(val name: String, val age: Int)

val user1 = User("Alice", 25)
val user2 = user1.copy(age = 26)
println(user1) // User(name=Alice, age=25)

Kotlin Kotlin vs Java

Kotlin Advantages:

  • πŸ”’ Concise Syntax: Reduces boilerplate code significantly
  • πŸ›‘οΈ Null Safety: Built-in null safety features
  • πŸ”„ Interoperability: 100% compatible with Java
  • ⚑ Modern Features: Extension functions, coroutines, lambda expressions
  • 🎯 Functional Programming: Higher-order functions support
  • πŸ“± Android First: Google's preferred language for Android

Both run on the Java Virtual Machine (JVM) and can use existing Java libraries and frameworks.

Kotlin List vs Array

Feature List Array
Size Dynamic (can grow/shrink) Fixed size
Type Flexibility Can store different types with generics Homogeneous (single type)
Modification Convenient add/remove methods Fixed size, overwrite only
Performance Some overhead for dynamic operations Better performance, contiguous memory

Kotlin lateinit vs lazy

πŸ• lateinit

Used with mutable properties that will be assigned later.

  • For var properties only
  • Non-null types only
  • Must be initialized before first access
class MyActivity : Activity() {
    private lateinit var binding: ActivityMainBinding
    
    override fun onCreate(savedInstanceState: Bundle?) {
        binding = DataBindingUtil.setContentView(...)
    }
}

πŸ’€ lazy

For expensive object creation that should be delayed until first access.

  • For val properties only
  • Thread-safe by default
  • Initialized on first access
val expensiveObject by lazy {
    // This block runs only once, on first access
    createExpensiveObject()
}

Kotlin Constructors

🎯 Primary Constructor

Declared directly in the class header. Concise and can initialize properties directly.

class User(val name: String, val age: Int)

// Usage
val user = User("Alice", 25)

πŸ”§ Secondary Constructor

Defined inside the class using the constructor keyword. Useful for additional initialization logic.

class User {
    var name: String
    var age: Int
    
    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }
}

Kotlin Visibility Modifiers

Modifier Accessibility Scope
public (default) Accessible everywhere Global
private Same class or file only Local
protected Class and its subclasses Inheritance hierarchy
internal Same module only Module-wide
class MyClass {
    public val publicProperty = "Everyone can see"
    private val privateProperty = "Only MyClass can see"
    protected val protectedProperty = "MyClass and subclasses"
    internal val internalProperty = "Same module only"
}

Kotlin Coroutines

A concurrency design pattern that simplifies asynchronous programming.

Key Benefits:

  • ⚑ Lightweight: Don't require separate threads
  • πŸ“– Sequential Code: Write async code that reads like sync
  • 🚫 Non-blocking: Don't block threads during execution
  • 🎯 Structured Concurrency: Better resource management
launch
async
runBlocking

Kotlin Coroutine Scopes

🌍 GlobalScope

Lives for entire application lifetime. Use with caution - can cause memory leaks.

🎯 CoroutineScope

Structured way to manage coroutines. Automatically cancels when scope is canceled.

πŸ“± Lifecycle-Aware Scopes (Android)

  • viewModelScope: Tied to ViewModel lifecycle
  • lifecycleScope: Tied to Activity/Fragment lifecycle
class MyViewModel : ViewModel() {
    fun fetchData() {
        viewModelScope.launch {
            // This coroutine will be cancelled when ViewModel is cleared
            val data = repository.getData()
            _liveData.value = data
        }
    }
}

Kotlin Coroutine Dispatchers

Dispatcher Purpose Use Case
Dispatchers.Main Main/UI thread UI updates, view interactions
Dispatchers.IO I/O operations Network calls, file operations, database
Dispatchers.Default CPU-intensive tasks Sorting, calculations, data processing
Dispatchers.Unconfined Starts in caller thread Not recommended for most cases
viewModelScope.launch {
    val data = withContext(Dispatchers.IO) {
        // Network call on IO thread
        repository.fetchData()
    }
    // Back to Main thread for UI update
    updateUI(data)
}

Kotlin Coroutines vs Threads

Feature Coroutines Threads
Weight Lightweight Heavy (OS-managed)
Blocking Non-blocking Blocking
Resource Usage Low memory overhead High memory overhead
Scalability Can create thousands Limited by system resources
Management Kotlin runtime Operating system

Kotlin Suspend Functions

Special functions that can be paused and resumed later without blocking the thread.

Key Features:

  • 🚫 Non-blocking: Don't block the calling thread
  • 🎯 Coroutine Context: Can only be called from coroutines
  • ⏸️ Suspendable: Can pause execution and resume later
  • πŸ”„ State Preservation: Maintains state during suspension
suspend fun fetchData(): String {
    delay(2000) // Simulates network call
    return "Data fetched successfully"
}

fun main() = runBlocking {
    println("Start")
    val data = fetchData() // Suspend function call
    println(data)
    println("End")
}

Kotlin Scope Functions

Special functions that create a temporary scope for an object to make code more concise and readable.

Function Returns Object Reference Use Case
let Lambda result it Null-checks, chaining
run Lambda result this Object initialization
with Lambda result this Multiple operations on object
apply Object itself this Object configuration
also Object itself it Additional actions (logging)

Kotlin Scope Functions Examples

// let - null checks
val name: String? = "Kotlin"
name?.let { println("Name is $it") }

// apply - object configuration  
val person = Person().apply {
    name = "John"
    age = 30
}

// run - initialization with result
val result = "Kotlin".run {
    println("This is $this")
    length // returns 6
}

// with - multiple operations
val builder = StringBuilder()
with(builder) {
    append("Hello, ")
    append("World!")
}

// also - additional actions
val numbers = mutableListOf(1, 2, 3)
    .also { println("List: $it") }
    .add(4)

Thank You!

Ready for your Android & Kotlin Interview

Good Luck! Keep Learning!