A junior developer is building a Jetpack Compose screen that displays a list of user profiles. They've noticed that whenever a single profile's 'like' status changes, the entire list recomposes, causing performance issues. The senior developer suggests using 'state hoisting'. What is the primary goal of state hoisting in this context?
Answer and explanation
Correct answer: A
State hoisting is a pattern of moving state up the composable tree to make child composables stateless. By doing this, the child composable (e.g., a single profile item) becomes dependent only on the inputs it receives. The state (like the 'like' status) is held by the parent, which can then decide to recompose only the specific child whose data has changed, rather than the entire list. This prevents unnecessary recompositions and improves performance.
Question 2
An application uses a Room database with a DAO that returns a Flow > to observe data changes. The UI layer collects this flow, but under heavy database write loads, the UI freezes because it's receiving updates too frequently. Which Flow operator is the most appropriate solution to apply before collecting the flow in the UI layer to mitigate this issue without losing the final state?
Answer and explanation
Correct answer: C
conflate() is designed for this exact scenario. When the collector is busy and cannot process an emission, conflate ensures that intermediate values are dropped, but the most recent value is always buffered and delivered to the collector as soon as it's ready. This prevents the collector from being overwhelmed while guaranteeing the UI eventually reflects the latest state.
Question 3
Multiple answers
A developer needs to schedule a background task using WorkManager that should only run when the device has a certain level of battery and is connected to a Wi-Fi network. Which of the following constraints should be applied to the WorkRequest? (Select TWO)
Answer and explanation
Correct answers: A, B
This constraint ensures the work will only run when the device is on an unmetered network, which is typically Wi-Fi. This correctly addresses one of the requirements.
This constraint defers the work until the device's battery is not considered low. This fulfills the requirement related to battery level.
Question 4
When writing a unit test for a ViewModel that uses viewModelScope to launch coroutines, what is the modern, recommended approach to manage the Dispatchers.Main dispatcher and control coroutine execution within a JUnit test?
Answer and explanation
Correct answer: B
This is the modern, recommended approach. The kotlinx-coroutines-test library provides runTest, which creates a TestScope and handles virtual time. A JUnit rule is used to inject a test dispatcher (like StandardTestDispatcher or UnconfinedTestDispatcher) into Dispatchers.Main before the test and clean it up afterward, ensuring the Main dispatcher is controlled during the test.
Question 5
To clear all data for a specific application package during development, a developer can use the Android Debug Bridge (adb). The command to achieve this is: adb shell pm clear ______.
Answer and explanation
Correct answer: A
The adb shell pm clear command requires the full package name of the application whose data you want to clear. For example, adb shell pm clear com.example.myapp would wipe all user data, cache, and databases for that specific app.
Question 6
Company Background: FitLife is a fitness tracking company modernizing its Android application. The current app was built five years ago using XML layouts and the traditional View system. The UI is inconsistent, slow to render complex screens, and difficult to maintain due to deeply nested LinearLayouts and RelativeLayouts inside a ScrollView.
Current Situation: The main dashboard screen is particularly problematic. It displays user stats, a list of recent workouts, and daily challenges. All this data comes from a DashboardViewModel which exposes several LiveData objects. The XML for this screen is over 800 lines long.
Requirements: The CTO has mandated a full migration of the dashboard screen to Jetpack Compose to improve performance and maintainability. The new implementation must:
Be built entirely with declarative UI components.
Observe the existing LiveData objects from the DashboardViewModel in a lifecycle-aware manner.
Replace the RecyclerView for recent workouts with a lazy-loading list in Compose.
Ensure the new UI is themable and supports Material 3 design principles.
Which of the following approaches is the most effective and idiomatic way to implement the new Jetpack Compose dashboard screen based on the requirements?
flowchart TD
subgraph ViewModel
A[LiveData ]
B[LiveData >]
C[LiveData ]
end
subgraph Compose UI
D{DashboardScreen}
E[StatsCard]
F[WorkoutList]
G[ChallengeBanner]
end
ViewModel --> D
D --> E
D --> F
D --> G
Answer and explanation
Correct answer: A
This approach correctly addresses all requirements. observeAsState() is the idiomatic, lifecycle-aware way to consume LiveData in Compose. LazyColumn is the direct replacement for RecyclerView for displaying lazy-loading lists. Wrapping the UI in MaterialTheme ensures it adheres to the specified design system. This solution is efficient, maintainable, and follows modern Android best practices.
Question 7
True or False: Jetpack DataStore is a direct, drop-in replacement for SharedPreferences and uses the same synchronous, file-based I/O API on the main thread.
Answer and explanation
Correct answer: B
This statement is false. While Jetpack DataStore is the recommended replacement for SharedPreferences, it is fundamentally different. DataStore uses Kotlin Coroutines and Flow for a fully asynchronous API, which prevents blocking the main thread and avoids the risk of ANR (Application Not Responding) errors that can occur with SharedPreferences' synchronous API.
Question 8
On Android 14 (API 34), an app that needs to perform a long-running task like a data sync must declare a foreground service. What is the critical requirement that the app must fulfill when calling startForeground() for a service related to data synchronization?
Answer and explanation
Correct answer: C
Starting with Android 10, and becoming more stringent in later versions like Android 14, you must declare a specific foregroundServiceType in your AndroidManifest.xml for any service that will be started in the foreground. This helps the system understand the purpose of the service and manage resources appropriately. For data synchronization, dataSync is the correct type.
Question 9
In an Espresso UI test, the app performs a network request that takes an unpredictable amount of time to complete before updating a TextView. The test intermittently fails with an NoMatchingViewException because the assertion runs before the TextView is updated. What is the most robust and recommended way to make Espresso wait for this asynchronous operation to complete?
Answer and explanation
Correct answer: B
This is the correct and idiomatic Espresso solution. An IdlingResource is a mechanism that allows your test code to signal to Espresso when the app is busy with a long-running operation. Espresso will pause the test and wait until the resource becomes idle before proceeding with the next action or assertion, making the test deterministic and reliable.
Question 10
In Jetpack Compose, a developer needs to display a potentially very long, vertically scrolling list of items. To ensure good performance, only the items visible on screen should be composed and rendered. Which composable should be used?
Answer and explanation
Correct answer: C
LazyColumn is the correct composable for this purpose. It is the Compose equivalent of RecyclerView. It only composes and lays out the items that are currently visible in the viewport, providing excellent performance for long or infinite lists.