Irbisa · Cheatsheet
Android Fundamentals
Activity, Fragment, lifecycle, Intent, Manifest, configuration changes
What are the four main Android app components, and why is
Applicationnot one of them?Walk through the Activity lifecycle: why does
setContentView()go inonCreate(), and when isonDestroy()called withoutonPause()/onStop()?class HomeActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (!session.isLoggedIn) { startActivity(Intent(this, LoginActivity::class.java)) finish() // next callback is onDestroy: no onStart, onResume, onPause or onStop…What happens to an Activity on screen rotation, and where do you keep state so it survives:
ViewModel,onSaveInstanceStateorrememberSaveable?class SearchViewModel(private val state: SavedStateHandle) : ViewModel() { // survives rotation (ViewModel) and process death (saved state) val query: StateFlow<String> = state.getStateFlow("query", "") fun onQueryChange(q: String) { state["query"] = q }}…What kinds of
Contextdoes Android hand you, and which one must never be held by a long-lived object?Where do you put code that must run before any Activity exists, and what should never be kept there?
@HiltAndroidAppclass ShopApp : Application() { override fun onCreate() { super.onCreate() crashReporter.install(this) // cheap, and useless if it starts late ProcessLifecycleOwner.get().lifecycle.addObserver(AppForegroundObserver)…What goes into
AndroidManifest.xml, and how do the manifests of your libraries end up merged into your app?<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" android:required="false" />…What do
minSdk,targetSdkandcompileSdkeach control, and what actually changes when you raisetargetSdk?// app/build.gradle.ktsandroid { compileSdk = 36 // APIs you can compile against defaultConfig { minSdk = 26 // oldest device that can install targetSdk = 36 // behaviour changes you have tested for…You add
res/values-ru/strings.xmlandres/drawable-xxhdpi/. How does Android decide which one a given device gets?What is an
Intent: explicit vs implicit, how does the system resolve an implicit one, and how do you get a result back?// Explicit: a screen in your own appstartActivity(Intent(this, DetailActivity::class.java).putExtra("id", 42L)) // Implicit: any app that can view a web pagetry { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com")))…What is a Fragment, how is its lifecycle tied to the host Activity, and why does it have a separate
viewLifecycleOwner?class ProfileFragment : Fragment(R.layout.fragment_profile) { private val viewModel: ProfileViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val name = view.findViewById<TextView>(R.id.name)…This Fragment crashes after rotation with "could not find Fragment constructor". What is wrong, and how should data get into a Fragment?
class ProfileFragment(private val userId: String) : Fragment(R.layout.fragment_profile) { private val viewModel: ProfileViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.load(userId) }} supportFragmentManager.commit { replace(R.id.container, ProfileFragment("42"))}How do runtime permissions work on Android, and what are the normal, dangerous and signature protection levels?
class ScannerActivity : ComponentActivity() { private val cameraPermission = registerForActivityResult( ActivityResultContracts.RequestPermission() ) { granted -> if (granted) openCamera() else showCameraUnavailable() } fun onScanClick() {…Which events trigger
onPause()withoutonStop(), and what do a dialog, multi-window and picture-in-picture do to the Activity lifecycle?Why do you pass objects between screens as
Parcelablerather thanSerializable, and why can a bigBundlethrowTransactionTooLargeException?// build.gradle.kts: plugins { id("kotlin-parcelize") }@Parcelizedata class Address(val city: String, val street: String, val zip: String) : Parcelable startActivity( Intent(this, CheckoutActivity::class.java).putExtra(EXTRA_ADDRESS, address)…What is process death, how do you reproduce it, and which state survives it?
# 1. Open the screen, fill in the form, press Homeadb shell am kill com.example.shop # 2. The process is gone (prints nothing)adb shell pidof com.example.shop…How do two Fragments exchange data (Fragment Result API, a shared ViewModel or an interface), and when do you pick each?
// Picker: sends a one-shot resultclass SortPickerFragment : DialogFragment() { private fun onPicked(sort: String) { setFragmentResult("sort_request", bundleOf("sort" to sort)) dismiss() }…What is the difference between
add()andreplace()in aFragmentTransaction, what doesaddToBackStack()do, and when do you needchildFragmentManager?supportFragmentManager.commit { setReorderingAllowed(true) replace(R.id.container, OrderDetailFragment.newInstance(orderId)) addToBackStack("detail") // Back returns to the list instead of closing the app}…What do
commit(),commitNow()andcommitAllowingStateLoss()do, and why does a commit crash with "Can not perform this action after onSaveInstanceState"?// wrong: the result can arrive while the app is stoppedviewModel.result.observeForever { result -> parentFragmentManager.commit { replace(R.id.container, ResultFragment.newInstance(result)) }} // right: events are delivered only while the view is at least STARTED…What do the launch modes
standard,singleTop,singleTaskandsingleInstancechange, and with stack A-B-C-D how do you get back to A?// A-B-C-D: return to the existing A, destroying B, C and DstartActivity(Intent(this, HomeActivity::class.java).addFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)) class HomeActivity : ComponentActivity() {…What is a
BroadcastReceiver, how do manifest and runtime receivers differ, and what changed for them in Android 8 and Android 14?class BootReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { // main thread, and the process may die right after this returns WorkManager.getInstance(context).enqueueUniqueWork( "resync", ExistingWorkPolicy.KEEP, OneTimeWorkRequestBuilder<SyncWorker>().build() )…What is a
ContentProvider, when do you actually need one, and how doesFileProviderlet another app open your file?// Manifest: FileProvider with authorities=${applicationId}.fileprovider, exported=false,// grantUriPermissions=true and meta-data FILE_PROVIDER_PATHS -> @xml/file_paths val uri = FileProvider.getUriForFile( context, "${context.packageName}.fileprovider", pdfFile)…This code crashes when the response arrives. Why, and how do
Looper,HandlerandMessageQueueget work back onto the main thread?class ProfileActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_profile) val nameView = findViewById<TextView>(R.id.name) Thread { val user = api.loadUserBlocking() nameView.text = user.name }.start() }}Find the bug: after leaving the splash screen, the app still opens the main screen two seconds later.
class SplashActivity : AppCompatActivity() { private val handler = Handler(Looper.getMainLooper()) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_splash) handler.postDelayed({ startActivity(Intent(this, MainActivity::class.java)) finish() }, 2_000) }}How does your Kotlin code actually run on Android: what is DEX, what replaced Dalvik, and how do JIT and AOT work together in ART?
Can one app run in several processes, and how do processes talk to each other through Binder, AIDL and bound services?
// IOrderService.aidl: interface IOrderService { int getCount(); } class OrderService : Service() { private val binder = object : IOrderService.Stub() { // runs on a Binder pool thread, so it must be thread-safe override fun getCount() = repo.count()…