My cheatsheet which includes my experience working with Android development. This does not include the ones that are already mentioned at other sites.
You can also check for others's for more detail:
- https://github.com/MindorksOpenSource/android-interview-questions
- https://android.jlelse.eu/android-interview-questions-cheat-sheet-part-ii-bea0633f0da7
-
Some cases when activity's lifecycle transition to another - Learn from here
- Configuration change occurs, which can also triggered by language changing.
- App enters multi-window mode and/or resized in this mode. Only the most recent activity that is interacted is in the
onResume()state, the other is inonPause()state. - New activity/dialog appears in the foreground, taking focus and partialy/entirely cover the current activity. The current activity enters
onPause()/onResume()respectively.
-
Activity launch modes - Learn from here
- SingleTop: If backstack contains A-B:
- A new intent arrives for B, B is singleTop: B receives
onNewIntent(). Backstack is now A-B. - A new intent arrives for A, A is singleTop: create new instance of A. Backstack is now A-B-A.
- A new intent arrives for B, B is singleTop: B receives
- SingleTask: Only 1 instance of that activity at the same time. If no instance: create a new task with that activity as the root. Else if there is an instance in another task, system routes the intent to that instance through
onNewIntent().
- SingleTop: If backstack contains A-B:
-
Passing data between fragments - Learn from here
-
How can you measure measure/layout performance - Learn from here
FrameMetricsAPI.
-
<include>, <merge> tag
-
How view renders? - Learn from here
-
Android internals for rendering a view? - Learn from here
-
Overdraw? - Learn from here
- Refers to the system's drawing a pixel on the screen multiple times in a single frame of rendering. For example, if we have a bunch of stacked UI cards, each card hides a portion of the one below it.
- Another source of overdraw: rendering transparent pixels (eg, any kind that involves transparency: shadows, fade-outs...).
-
Should we call
invalidate()frequently for views? - Learn from here- Use alternative methods like
postInvalidate(),postInvalidateOnAnimation(), etc.
- Use alternative methods like
-
Adaptive icons - Learn from here
- Introduced from android 8.0, which can display a variety of shapes accross different devices.
-
Outline provider - Learn from here
- Used to clip views, which will change views's casting shadow.
- When set to null, view won't have shadow.
-
AnimatedImageDrawableandAnimatedVectorDrawable- Learn from here- They works simillarly in that the render thread drives the animations. And the render thread also uses a worker thread to decode.
-
ImageDecoder - Learn from here
- Can handle gifs, WebP (which it will return an AnimatedImageDrawable).
- Can decode image from byte buffer, file or URI.
- Can perform post-processing, error handling, cropping, scaling.
-
Doze and App Standby - Learn from here
-
FlatBuffers - Learn from here
- Access to serialized data without parsing/unpacking: represents hierarchical data in a flat binary buffer in such a way that it can still be accessed directly without parsing/unpacking.
- Memory efficiency and speed.
- Flexible: offers optional fields: has backward compatibility.
- Strongly typed.
-
Process - Learn from here
- By default, all components of the same application run in the same process. However, if you find that you need to control which process a certain component belongs to, you can do so in the manifest file.
- Interprocess communication(IPC): Learn from here
-
Thread - Learn from here
- Main thread: - Learn from here
- In charge of dispatching events to the appropriate user interface widgets, including drawing events.
- All components that run in the same process are instantiated in the UI thread, and system calls to each component are dispatched from that thread
- Thread priority: - Learn from here
- Threads in
foreground groupgets ~ 95% of total execution time for device. - A newly created one will with same priority and group memberships as spawning thread.
- One cpu core can serve a process/thread at a time. Too many threads will go into
priority and schedulingissue. - Kotlin's coroutine IO dispatcher allocates additional threads on top of the ones allocated to the default dispatchers to do IO-bound code (and hence fully utilize CPU resources).
- Threads in
- Main thread: - Learn from here
-
Install-time permission - Learn from here
-
Run-time permission - Learn from here
-
Special permission - Learn from here
-
Android 13 - Learn from here
- Introduce battery-perserving measures: Learn from here
- Foreground Services Task Manager: Learn from here
-
Android 11 - Learn from here
- One-time permission.
- Permissions auto-reset.
- Update how media controls are displayed.
- Chat bubbles.
- Improve IME transitions.
- Introduce Quick Access Device Controls feature: allows the user to quickly view and control external devices such as lights, thermostats, and cameras from the Android power menu.
- Storage, location updates.
- NN API 1.3.
- NDK
ImageDecoderAPI.
-
Android 10 - Learn from here
- Foldables.
- 5G.
- Smart reply in notifications: uses on-device ML to suggest contextual actions like replies for messages or opening a map for an address in the notification. App can custom its own replies.
- Dark theme: adds system-wide dark theme (ideal for low light/helps save battery). System can also create dark theme dynamically for apps (Force Dark feature).
- Gesture navigation: eliminates nav bar, use edge swipes instead.
- Settings panel: app can show key system settings(network, NFC, volume) directly in a floating panel.
- Sharing shortcuts: let user jump directly to a specific activity in apps with content attached.
- Privacy for users:
- More control over location data: new permission option that allow app to access location only when foreground.
- Preventing device tracking: apps can no longer access non-resettable ids like device serial number, etc. Device's MAC address is randomized when connected to WIFI.
- Apps are given scoped access into external storage(don't need to request any storage-related permission): can see files in app-specific directory, medias that app created from media store.
- Blocking unwanted interruptions: prevent app launches unexpectedly.
-
Pie (Android 9) - Learn from here
- Display cutout support.
- Notification enhancements: Users can reply/enter text directly from a notification, apps can display images in messaging notifications.
- Multi-camera support and camera updates: access streams simultaneously from 2 or more physical cameras.
- Introduces
ImageDecoderfor drawables and bitmaps:. - Introduces
AnimatedImageDrawablefor drawing and displaying GIF and WebP animated images. - Adds support for HDR VP9 profile.
- Adds support for encoding images using High Efficiency Image File format(HEIF or HEIC), which improves compression and reduces storage space and network.
- Data cost sensitivity for
JobScheduler: can use network status to improve the handling of network-related jobs. - New rotation mode that lets user manually change device orientation by pressing a button in the system bar.
- Added
Precomputed Text: compute and cache required information ahead of time, and this will be performed off the main thread. - Limit access to sensors for background apps: cannot access mic/camera, or receive events from accelerometers, etc.
- Other privacy changes: restrict access to phone numbers without permissions, access to wifi location and connection information.
- Power management: Learn from here
- App Standby Buckets: system limits device resources(CPU, battery) available to each app based on which prioriy bucket the app is in (Active, Working set, Frequent, Rare, Never).
- Battery saver improvements: background apps do not have network access, location service may be disabled when screen if off, etc.
-
Oreo (Android 8.0) - Learn from here
- Picture-in-picture.
- Notifications:
- Notification channels.
- Notification dots.
- Snoozing.
- Autofill framework: helps fasten the process of filling in fields.
- Downloadable fonts: apps can request fonts from a provider application instead of bundling fonts into APK. This will reduces APK size, allows multiple apps to use the same font, which will saves cellular data, phone memory and disk space.
- Autosizing TextView.
- Adaptive icons: can display a variety of shapes accross different devices.
- Multi-display support: users can move an activity that supports multi-window to another display.
- App categories: app can declare a category, which is used to group apps of similar purpose.
- Neural Networks API (NNAPI).
- Background execution limits:
- Background service limits: While an app is in background (does not have a visible activity or does not have a foreground service running/connected to it), system limits its use of background services(by killing those services when it goes into idle state).
- Broadcast limits: apps can no longer register broadcast receiver in manifest for implicit broadcast(except some) because this may trigger many apps to consume resources. They can still register at runtime.
- Background location limits: limits how frequently an app can retrieve location while running in background.
SharedMemoryAPI: share data between apps or between multiple processes within a single app.
-
Nougat (Android 7.0) - Learn from here
- Multi-window support.
- Notification enhancements - Learn from here.
- Improve Doze: applies some CPU and network restrictions on app even when device is not stationary. - Learn from here
- Remove 3 implicit broadcasts:
CONNECTIVITY_ACTION, ACTION_NEW_PICTURE, ACTION_NEW_VIDEO, as they can wake up background processes of multiple apps at once and hence not good for memory and battery. - SurfaceView: now has synchronous movement, which improves battery performance(composited in dedicated hardware).
- Introduce Data Saver mode: enables user to control over the cellular data usage by apps.
- Integrates Vulkan API into the platform.
- Quick Settings Tile API: more room, can change what and where tiles are displayed.
- Number blocking.
- Support more languages.
- Webview: ChromeAPK is used to render Android system webview.
- OpenGL ES 3.2 API.
FrameMetricsAPI: allows to monitor UI rendering performance, by providing timing data that the rendering system reports.- Introduce App Shortcuts - Learn from here.
- Image keyboard support: let user input images and other contents directly in a keyboard.
- Storage manager intent: taking user to the system's free up space screen.
-
Marshmallow (Android 6.0) - Learn from here
- Introduce Run-time permission.
- Doze and App Standby.
- Apache HTTP Client Removal.
- TextSelection: when user selects text, can show actions like copy, cut, etc in a floating toolbar.
- App can no longer forced device to connect to a specific wifi network.
- APK file is considered corrupt is a file is declared in manifest file but not present in the APK.
- Camera: accessing shared resources in camera service prefer high-priority processes, and switch user will cause current camera client used by app to be evicted.
-
Lollipop (Android 5.0) - Learn from here
- ART runtime: includes AOT compilation, improves garbage collection.
- Improve audio and graphics pipelines.
- View now have translation Z to have shadows.
- Activity transitions.
Vector drawables.- Introduce heads-up notification: small floating window that allows the user to respond or dismiss without leaving the current app.
- Multi-networking features: app can query for available networks, request a connection and respond to connectivity lost/gain.
- Support for OpenGL ES 3.1.
- Multi-channel audio stream mixing, new MediaSession API for controlling media playback.
- From API >= 21: webview no longer allows mixed content and 3rd party cookies by default.
- Retrofit vs OkHttp - Learn from here
-
Retrofit:
- Structured URL and parameter construction.
- Received API response as our desired object model(by providing a GSON converter factory).
- Put network call to background thread automatically and send result to main thread.
-
OkHttp:
- Construct request manually
val request = Request.Builder().url("$BASE_URL$BASE_PATH/?" + "$PARAM_ACTION=$VALUE_QUERY&$PARAM_FORMAT=$VALUE_JSON&" + "$PARAM_LIST=$VALUE_SEARCH&$PARAM_SRSEARCH=$searchString") .build()
- Deserialize the result ourselves:
result = Gson().fromJson(..., Result.class) - API result is called on background thread.
- More dynamic URL formation.
-
- DiskCacheStrategy - Learn from here
- NONE: cache nothing (will still saved in mem cache, so if want to load image from server only, also include skipMemCache = true)
- DATA: cache only the original full-res image.
- RESOURCE: cache only the final image, after scaling resolution or transformations.
- ALL: cache all versions of the image.
- AUTOMATIC: intelligently choose a cache strategy based on the resource.
-
StringBuffer vs StringBuilder - Learn from here
StringBuffer StringBuilder Synchronized Not synchronized Thread safe Not thread safe Slower Faster
-
Coroutines - Learn from here
- Suspending functions do not block the caller thread, but needed to use the
withContext(Dispatchers).
- Suspending functions do not block the caller thread, but needed to use the
-
Coroutine Dispatchers - Learn from here
- Default: optimized to do CPU-bound functions.
- Backed by a thread pool with as many threads as there are CPU cores in system.
- Does not over-allocate threads.
- IO: optimized to execute IO-bound codes.
- If a device has 4 core with 4 threads allocated to default dispatcher, and all of them are blocked in IO: our device is under-utilized.
- Allocates addtional threads on top of the ones allocated to the default dispatcher, so can fully utilize machine's CPU resources and do blocking IO at the same time.
- Default: optimized to do CPU-bound functions.
-
CPU-bound code vs IO-bound code - Learn from here
- CPU-bound code: consume CPU resources.
- IO-bound code: Does not actually consume CPU resources.
-
Inline function - Learn from here
- No runtime overhead.
- Assume we have a function like:
fun nonInlined(block: () -> Unit) {
println("before")
block()
println("after")
}And when we called it from kotlin:
nonInlined {
println("do something here")
}Under the hood, it will create an instance of Function to wrap the code inside the lambda:
nonInlined(new Function() {
@Override
public void invoke() {
System.out.println("do something here");
}
});So basically, calling this function and passing a lambda to it will always create an instance of a Function object(OVERHEAD!). If use the inline keyword: no Function instance will be created, instead, the code around the invocation of block inside the inlined function will be copied to the call site, so you'll get something like this in the bytecode:
System.out.println("before");
System.out.println("do something here");
System.out.println("after");- Delegates - Learn from here
- A class that provides the value for a property and handles its changes. This allows us to move, or delegate, the getter-setter logic from the property itself to a separate class, letting us reuse this logic.
- Provided with the property it's working with via instance of KProperty class, and an object that has the property.
class FragmentArgumentDelegate<T: Any> : ReadWriteProperty<Fragment, T> { }-
Scoped functions - Learn from here
-
StateFlow - Learn from here
- A state-holder observable flow that emits the current and new state to the collectors.
- Unlike Flow,
StateFlowis hot: collecting from the flow does not trigger any producer code. When a new consumer starts collecting from the flow, it receives the last state in the stream and any subsequent states. - Always have an initial value, keeps the last emitted one.
- Its active instance exists independently from the consumers.
- All methods of state flow are thread-safe and can be safely invoked from concurrent coroutines without external synchronization.
-
StateFlow vs LiveData - Learn from here
- Both are observable data holder classes.
- LiveData.observe() automatically unregister the consumer when the view goes to
STOPPEDstate, wheres collecting fromStateFlowand any other Flow does not stop collecting automatically. To achieve the same behavior, need to collect the flow from aLifecycle.repeatOnLifeCycleblock.
- Add a new fragment, it has enter animation but does not have exit animation? - Reason
- Here's the logcat:
E/FragmentManager: No field with the name mListener is found in Animation class
java.lang.NoSuchFieldException: No field mListener in class Landroid/view/animation/Animation; (declaration of 'android.view.animation.Animation' appears in /system/framework/framework.jar!classes3.dex)
at java.lang.Class.getDeclaredField(Native Method)
at androidx.fragment.app.FragmentManagerImpl.getAnimationListener(FragmentManager.java:1301)
at androidx.fragment.app.FragmentManagerImpl.setHWLayerAnimListenerIfAlpha(FragmentManager.java:1283)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1811)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2426)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2372)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)-
Achieve toolbar menu ripple effect - Learn from here
- In short:
?attr/actionBarItemBackground.
- In short:
-
Make fading edge for a view - Learn from here
- Look for the
getLeftFadingEdgeStrength()and other relative methods.
- Look for the
-
Only allow to perform click on a portion of a custom view?
- Override
onTouchEvent(). Remember to check if you actually need to handle (if your custom view does not set any click listener, and the parent view group has set a click listener to do something ...)
- Override
@Override
public boolean onTouchEvent(MotionEvent event) {
// We draw everything in this view, so manually handle click if there is any click listener set to it (don't want it
// to always consume touch event, if so, the touch event won't be passed to other views that is below this view)
if (!hasOnClickListeners())
return super.onTouchEvent(event);
// Width is larger than visible content
boolean insideTouchRegion = checkIfInsideTouchRegion(event);
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
if (insideTouchRegion) {
performClick();
}
return insideTouchRegion;
}
return insideTouchRegion;
}-
Layout Res Id in constructor - Learn from here
- No longer needed to override
onCreate()/onCreateView()in activity/fragment to set layout.
- No longer needed to override
-
OnBackPressedDispatcher - Learn from here
- No longer needed to override
onbackPressed()of activity to achieve logics you want, instead use this method in any place that has access to activity. This will gives more flexibility.
- No longer needed to override
-
FragmentContainerView - Learn from here
- If using
FrameLayoutas a parent to your fragment, use this instead. It fixes some bugs include window insets dispatching.
- If using
-
How View model survives orientation change? - Learn from here
- Using
NonConfigurationInstancesto get the savedViewModelStore. - And yes, viewModel won't survive low memory or
finish()scenarios, cause the viewModelStore will be cleared in those scenarios.
- Using
