74 Mobile Essentials interview questions with detailed answers, sorted from basic to advanced. Free to practice, with progress saved automatically.
A curated shortlist for mobile interviews, spanning Flutter, Android and React Native. It covers widgets and UI, Activity and Fragment lifecycles, Jetpack Compose, Dart isolates, the BLoC pattern, app architecture, state management, list performance, networking with caching, security, and code signing when releasing an app.
A Future is a value that arrives once in the future (like a JS Promise); a Stream is a sequence of values arriving over time, like a conveyor belt. In Flutter, FutureBuilder builds UI from a Future and StreamBuilder builds UI from a Stream. Streams…
A StatelessWidget depends only on its constructor arguments (and any InheritedWidgets it reads); a StatefulWidget adds a long-lived State object that holds mutable data while the widget stays in the tree. - StatelessWidget: build() runs again when the parent rebuilds it with new arguments, or…
BuildContext is a widget's "address" in the tree — under the hood it is that widget's Element. Every "look up the tree" operation goes through a context: Theme.of(context), MediaQuery.of(context), Navigator.of(context), ScaffoldMessenger.of(context). Because of(context) searches upward from the context's position, which context you use decides the…
Flutter splits the UI into three trees with different jobs: the widget is the description, the element is the "live instance" that holds position and state, and the render object does layout and painting. - Widget tree: immutable, cheap objects recreated on every build(). A…
A Key lets Flutter recognise "this is still the same widget" when its position among its siblings changes. An element compares the new and old widgets with Widget.canUpdate: same runtimeType and same key. Without keys, Flutter matches only by type + position. A common bug:…
A const constructor creates the object at compile time, and two identical const expressions return the same instance (canonicalization). That is where the Flutter benefit comes from: when a parent rebuilds, the element compares the new widget with the old one. If the child is…
setState() tells the framework that data inside a State changed: it runs the callback synchronously, then marks the element dirty (markNeedsBuild). Flutter calls build() again on the next frame rather than immediately, and several setState calls in the same frame cause only one build. Rules…
BLoC (Business Logic Component) separates logic from UI in one direction: the UI sends events in, the BLoC processes them and emits new states, and the UI simply renders the state. The usual packages are bloc + flutterbloc. On the UI side: BlocProvider provides the…
The three most common options differ mainly in how much architecture they impose: Provider Riverpod BLoC / Cubit ------------ What it is Wrapper around InheritedWidget + ChangeNotifier A rewrite of Provider, independent of BuildContext Event → state flow built on Stream Missing provider ProviderNotFoundException at…
Navigator 1.0 is an imperative API: you push and pop each screen on the stack yourself. Navigator 2.0 (the Router API) is declarative: the screen stack is derived from app state, usually the URL. gorouter is the Flutter team's package that wraps the Router API…
Clean architecture separates code into layers: Presentation (UI), Domain (business logic, entities, use cases), and Data (repositories, data sources). What makes it clean architecture is the dependency rule: outer layers may depend on inner layers, never the other way around. Presentation calls Domain, Data implements…
A suspend function can pause without blocking its thread, then continue once the result is ready. It can only be called from a coroutine or from another suspend function. Mechanism: the compiler turns a suspend function into one that takes an extra hidden Continuation parameter…
The Activity lifecycle is the sequence of callbacks the system invokes as a screen is created, becomes visible, loses focus, gets covered and is destroyed: - onCreate(): one-time setup — setContent/setContentView, obtain the ViewModel, read savedInstanceState. - onStart(): the Activity becomes visible. - onResume(): in…
An Intent is a "request" object handed to the system to start a component: open an Activity, run a Service, send a broadcast. There are two types: - Explicit intent: names the exact target component — typically used inside your own app. - Implicit intent:…
A Service is a component for work that needs no UI. It runs on the process's main thread, so heavy work still has to be moved to a coroutine or another thread. Three forms: - Started service (startService): runs until it calls stopSelf() or is…
Android groups permissions by risk: - Normal (INTERNET, VIBRATE): declared in the manifest and granted at install time. - Dangerous / runtime (camera, location, contacts, microphone, POSTNOTIFICATIONS since Android 13): since Android 6.0 (API 23) they must be requested at runtime; the user can deny…
mutableStateOf() creates a MutableState<T that Compose observes: any composable reading .value is recomposed when the value changes. remember keeps that object across recompositions — without remember, every recomposition creates a fresh state reset to its initial value. Variants worth knowing: - rememberSaveable: survives rotation and…
MVVM (Model-View-ViewModel) separates UI logic from business logic into three parts: - Model: holds data and business rules, usually repositories, Room, APIs. - View: displays the UI (Activity/Fragment/Composable). The View does not handle logic itself; it only renders state and sends user events up to…
Both hold a current value and notify observers when it changes, but they come from different places: LiveData is an Android class and lifecycle-aware out of the box; StateFlow is part of Kotlin coroutines and has no Android dependency. LiveData StateFlow --------- Initial value Optional…
A ViewModel is a screen's state holder: it keeps and prepares data for the UI and survives configuration changes (rotation, dark-mode switch) — the Activity is recreated but the ViewModel stays, so the API is not called again. Its proper role according to Android's architecture…
Room is the Jetpack library on top of SQLite: you declare entities and queries with annotations, Room generates code at compile time (via KSP) and validates your SQL at build time. Compared with using SQLiteOpenHelper directly: - A wrong column name or SQL syntax →…
Interceptors sit in front of HTTP requests and responses so you can modify them. - addInterceptor registers an application interceptor, which runs once per request. addNetworkInterceptor { ... } registers a network interceptor, with the same lambda form but running for every actual network call…
Hermes is an open-source JavaScript engine Meta built specifically for React Native, optimized for startup time, memory and app size. JSC (JavaScriptCore) is Safari's engine and used to be RN's default. Key differences: - Ahead-of-time bytecode: at build time Hermes compiles the JS bundle to…
RN computes layout with Yoga (Meta's C++ engine). Flexbox works much like the web, but the defaults differ — this is where web developers usually trip: React Native Web CSS --------- flexDirection column row flexShrink 0 1 alignContent flex-start stretch flex accepts a single number…
Stack Navigator: push/pop navigation — a new screen stacks over the previous one. There are two flavours: @react-navigation/native-stack uses UINavigationController (iOS) and Fragment (Android), so animations and gestures are handled by the platform — the default choice; @react-navigation/stack is written in JS, more customisable animations…
FlatList virtualizes: it mounts only items inside the "window" (visible area + buffer on each side) and unmounts items outside as you scroll. Memory is roughly constant regardless of total item count. Key knobs: - windowSize (default 21): how many viewport heights of content stay…
Same rules as React on the web: memoization only helps when you need a stable reference for something that compares references (React.memo, dependency arrays, FlatList props). The difference is that on low-end Android devices, wasted renders in a long list turn into scroll jank more…
New Architecture is the umbrella for three pieces Meta rewrote in RN since 2020: 1. JSI (JavaScript Interface): a C++ layer that replaces the old Bridge. The JS engine holds direct references to C++/native objects and calls them synchronously, no JSON serialization. 2. TurboModules: the…
Animated API (built into RN core): - With useNativeDriver: true, the whole animation is sent to native before it starts and runs on the UI thread, so it stays smooth even when the JS thread is busy. - Limit: the native driver only animates properties…
Mobile push notifications always go through the OS vendor's service: APNs (Apple Push Notification service) for iOS and FCM (Firebase Cloud Messaging) for Android. The app asks the OS for a push token identifying the device, sends the token to the backend, and the backend…
- Hot reload: injects the changed Dart code into the running Dart VM and rebuilds the widget tree, keeping app state. Very fast, great for UI tweaks. Does not re-run main() or initState(). - Hot restart: restarts the app, rebuilding everything from scratch → state…
Pick by data shape: - sharedpreferences: simple key–value pairs (flags, settings, user preferences). Not for large/structured data. - Files: read/write files in the app directory for blobs/documents. - SQLite (sqflite): a relational database for structured data, complex queries, table relationships — the basis for offline-first.…
A Fragment is a reusable UI component with its own lifecycle, living inside an Activity (or another Fragment) — used to split the UI into pieces and support multi-size layouts (phone/tablet). Key differences: - Fragments add view-related callbacks: onCreateView() (create the view), onViewCreated(), onDestroyView() —…
Compose is a declarative UI: you write @Composable functions that take data (state) and emit UI from it. When state read inside changes, Compose re-runs the affected composables to update the UI — that is recomposition. Key points: - Compose only recomposes the parts that…
The Navigation Component standardizes in-app navigation into a declarative navigation graph, replacing scattered manual FragmentTransaction/intents. Key concepts: - NavGraph: the set of destinations and the paths between them. - NavHost: the container showing the current destination. - NavController: drives navigation (navigate(), back stack). Benefits: -…
RN uses the same React hooks as React web (hooks are not tied to the DOM). - useState: declares state in a function component; calling the setter re-renders the component. - useEffect: runs side effects (API calls, subscriptions, timers) after render. The dependency array controls…
RN runs two main threads, each needing to hit ~60fps (16ms/frame): - JS thread: runs React logic, handles events, decides the UI. If busy (heavy computation, rendering big lists, too many console.logs), JS misses the frame deadline → jank while scrolling/interacting. - UI (native/main) thread:…
Beyond per-screen lifecycles, a mobile app also has an app-wide state managed by the OS: open (foreground), running in the background, or reclaimed by the system (killed). Why it matters: - Going to the background, you should stop camera/animation/timers, save state, and drop heavy connections…
Mobile networks are flaky and battery-costly, so the networking layer must be robust: - API calls: in React Native use fetch or axios. Set timeouts (fetch has none built in; use an AbortController), cancel requests on screen exit, and handle errors and loading states clearly.…
A deep link is a URL that opens an app to a specific screen/content (e.g. an ad link opening straight to a product page), rather than just the home screen. Types: - Custom URL scheme (myapp://product/12): simple, works on all versions, but unverified — another…
Before hitting the store, an app must be code-signed with a certificate — this is how the platform verifies the origin and integrity of the build. Why it is needed: - Ensures the app comes from the right developer and was not modified after signing.…
Both help an app work well across many sizes (phone, tablet, foldable, desktop) but differ in emphasis: - Responsive: adjusts the arrangement of the UI to fit the available space — resizing, changing column counts, wrapping. E.g. 1 column on a phone → 2–3 columns…
A device can be lost, rooted or jailbroken, or the app can be reverse-engineered, so never treat the client as a trusted environment. Storing sensitive data - Keep tokens, passwords and keys in the OS secure store: Android Keystore, iOS Keychain. On RN use react-native-keychain,…
Both defer initialization of a non-null property, but they differ in who initializes it and when: lateinit var val ... by lazy { } --------- Variable kind var (reassignable) val (read-only) Who assigns Outside code assigns later (DI, onCreate, a test's setUp) The lambda runs…
They differ in what draws the UI and what platform the code runs on: - Native: written separately per platform — Kotlin/Java for Android, Swift for iOS. Full access to system APIs and the best performance, but two codebases to maintain. - Hybrid: a web…
- versionCode: an internal integer that users never see. Google Play and the OS use it to tell which build is newer: each upload must be greater than the previous one, and Android refuses to install a build with a lower versionCode than the installed…
Flavors are build variants of the same codebase for each environment — typically dev, staging, production. Each flavor can have its own app name, icon, API endpoint, feature flags and application ID (Android calls this a product flavor, which combines with the debug/release build type…
The cause: in the background the OS suspends or throttles the JS thread, so setInterval stops firing. If you decrement remaining - 1 every second, the timer looks frozen or off when the user returns. The right approach: store the end timestamp (deadline), not the…
You cannot sit next to every user, so the app needs a crash reporting SDK (Firebase Crashlytics, Sentry) that collects crashes into a dashboard: grouped by stack trace, counting affected users, filterable by app version/OS/device. In Flutter you must catch two error sources: errors inside…
When memory is low, the OS kills the process of a backgrounded app (process death). Unlike the user closing the app, on return Android recreates the same screen (iOS still shows the old screen's snapshot in the app switcher), so the user expects the app…
Both stores follow the same flow: signed build → distribute to testers → review → gradual release. Google Play: 1. Build a signed App Bundle (AAB) with a versionCode higher than the previous one. 2. Upload to test tracks: internal (up to 100 testers, available…
Biometrics do not replace server authentication — they only unlock something already stored on the device (usually a refresh token) or confirm an action (a money transfer). The weak way: show the prompt, get true/false, and let the user in. The result is just a…
A WebView suits content that changes often or already exists on the web: terms pages, promotions, partner mini apps, payment gateway pages. Content changes need no new app release. The trade-off: more memory, less native scrolling/animation, and a new security surface. Two-way communication (react-native-webview): -…
The usual cause: images are decoded at their original size. An image in memory is uncompressed, roughly width × height × 4 bytes — a 4K image (3840×2160) takes over 30 MB of RAM even if it is shown as a 120×120 thumbnail. A few…
Context is the bridge to system resources and services: accessing resources, starting Activities/Services, getSystemService(), opening databases, etc. Two main flavors differ by lifecycle: - Activity context: tied to one Activity's lifecycle and aware of theme/UI. Use it when correct theming matters: inflating layouts, creating Dialogs,…
An ANR is the system dialog shown when the main (UI) thread is blocked too long and the app stops responding. Key thresholds: - No response to an input event (touch, key) within 5 seconds. - A BroadcastReceiver.onReceive() runs too long (10 seconds foreground, 60…
RecyclerView efficiently renders large lists/grids by reusing a small pool of Views instead of creating one per item. Picture a window showing only a few rows: as you scroll, a row leaving the screen isn't destroyed — it goes into the RecycledViewPool and is re-bound…
InheritedWidget is a special widget that lets descendant widgets read data from an ancestor without threading it manually through every constructor. It is the underlying mechanism that Provider, Theme, and MediaQuery are all built on. Picture it as a "broadcast station" placed high in the…