Posts

What is Canvas api in Android ?

In Jetpack Compose, the   Canvas API   is a declarative, stateless way to draw custom shapes, paths, and images. Unlike the traditional View system where you override   onDraw(canvas) , Compose uses a   Canvas   composable that provides a   DrawScope . Canvas(modifier = Modifier.size( 200. dp)) { // The DrawScope starts here drawCircle( color = Color.Blue, radius = size.minDimension / 4 , center = center // 'center' and 'size' are provided by DrawScope ) } Lifecycle The Canvas follows the standard Compose  "Three Phases"  of a frame, but it spends most of its time in the final phase. Composition (What to show) Compose determines that a  Canvas  should be part of the UI tree. If you use  mutableStateOf  inside your  onDraw  block, Compose tracks this as a dependency. Layout (Where to show it) The  Modifier.size()  or constraints from the parent determine the Canvas's hei...

How do you Handle Configuration Change ?

Configuration changes such as screen rotation , multi-window, foldable postures, changing locale cause the activity to be recreated, which means all Activity fields are lost. Core Principal  - UI State should not live inside activity. There are 3 ways to save the data , ViewModel  : Hold the UI state in memory and survives configuration change. It has much longer lifespan as the old viewModel can be reused inside new Activity. SaveStateHandle  : Lightweight, Bundle backed storage. Its fast but size is limited ~1MB. Proto Datastore  : Disk based persistance. Survives  process death  (Force kill, low memory) Safest, ensure state is restored when relaunched.

What are the android lifecycle events ?

  The Activity lifecycle defines how Android creates, displays, pauses, and destroys a screen. Correct usage ensures good performance, no leaks, and a smooth user experience. onCreate()  : Called once when activity is created. best for , Dependency Injection Initializing ViewModels onStart()  : The Activity becomes visible but not yet interactive. Good place for creating observers onResume()  : The Activity is in the foreground and  fully interactive. Start Sensors, Camera or Location Updates. Perform data Synchronization Resume animations or realtime updates onPause()  : Called when activity is about to lose focus. Used to pause or suspend ongoing work. Best place to pause Camera, Sensors, Listeners. onStop()  : When activity is no longer visible. Used to release resources like Media Playback. onDestroy()  : Final Cleanup when activity is destroyed.

What is a Companion Object ?

In Kotlin, a companion object is a special type of object declaration that is tied to a specific class. It allows you to define members (properties and functions) that belong to the class itself rather than to instances of the class. Key Characteristics : Scoped to the Class: You don't need to create an object (instance) to access its contents. Single Instance: Only one companion object exists for each class. Access to Private Members: The companion object can access private members of its containing class. Interface Implementation: Unlike Java's static , a companion object can implement interfaces and be treated like a real object. class User(val id: Int, val name: String) { // This is the companion object companion object { const val MIN_PASSWORD_LENGTH = 8 fun createDefaultUser(): User { return User(0, "Guest") } } } // Accessing members directly via the class name fun main() { println(User.MI...

Kotlin inline, noinline and crossline

👉    What is an  inline  function in Kotlin? When we should use it and when not ? 1. Higher-Order Functions with Lambdas This is the primary reason for inline . If your function accepts a lambda, inlining can prevent the overhead of creating an anonymous class for that lambda. inline fun<T> measureTime(block: () -> T): T { val start = System.currentTimeMillis() val result = block() println("Elapsed time: ${System.currentTimeMillis() - start}ms") return result } 2. Using reified Type Parameters In Kotlin/JVM, type information is erased at runtime. If you need to check a generic type (e.g., T is String ), you must use an inline function with a reified parameter. inline fun <reified T> List<Any>.filterIsInstance(): List<T> { val result = mutableListOf<T>() for (item in this) { if (item is T) result.add(item) } return result } 3. Non-Local Returns Inside a lambda passed to an inline function, you can use ...