▸ System creates a new activity instance ▸ When this happens ▸ On low memory ▸ Con fi guration changes ▸ Don’t keep activities 7 Shibuya.apk #42 source: https://developer.android.com/guide/components/activities/activity-lifecycle
{ var count: Int = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) savedInstanceState?.getInt("count")?.let { count = it } // … } override fun onSaveInstanceState(outState: Bundle) { outState.putInt("count", count) super.onSaveInstanceState(outState) } } 14 Save the value for the new instance Shibuya.apk #42
{ var count: Int = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) savedInstanceState?.getInt("count")?.let { count = it } // … } override fun onSaveInstanceState(outState: Bundle) { outState.putInt("count", count) super.onSaveInstanceState(outState) } } 15 Restore the saved value if present Shibuya.apk #42
any type of the value ▸ rememberSaveable ▸ Remember Bundle-supported type of the value ▸ Add more support with Parcelable framework or Saver interface 21 Shibuya.apk #42
val countRepository: CountRepository, ) : ViewModel() { private val countMutation = MutableStateFlow(0) val count: StateFlow<Int> = countMutation.asStateFlow() } class MyFragment : Fragment() { private val viewModel: MyViewModel by viewModels() } 30 Shibuya.apk #42 ViewModel instance is kept during con fi guration changes
val countRepository: CountRepository, ) : ViewModel() { private val countMutation = MutableStateFlow(0) val count: StateFlow<Int> = countMutation.asStateFlow() } class MyFragment : Fragment() { private val viewModel: MyViewModel by viewModels() } 31 Shibuya.apk #42 ViewModel instance is lost when Activity is destroyed for low memory…
val countRepository: CountRepository, private val savedStateHandle: SavedStateHandle, ) : ViewModel() { private val countMutation = MutableStateFlow( savedStateHandle["count"] ?: 0 ) val count: StateFlow<Int> = countMutation.asStateFlow() fun saveState() { savedStateHandle["count"] = countMutation.value } } class MyFragment : Fragment() { private val viewModel: MyViewModel by viewModels() override fun onSaveInstanceState(outState: Bundle) { viewModel.saveState() } } 33 Shibuya.apk #42 Use SavedStateHandle to save and restore values
UI element states class MyValueState( private val countRepository: CountRepository, initial: Int, ) { var count: MutableState<Int> = mutableStateOf(initial) private set } 34 Shibuya.apk #42
view element states class MyValueState( private val countRepository: CountRepository, initial: Int, ) : SavedStateRegistry.SavedStateProvider { var count: Int = initial override fun saveState(): Bundle = bundleOf( "count" to count ) } 38 Shibuya.apk #42
view element states class MyValueState( private val countRepository: CountRepository, initial: Int, registryOwner: SavedStateRegistryOwner, ) : SavedStateRegistry.SavedStateProvider { var count: Int = initial init { registryOwner.lifecycle.addObserver( LifecycleEventObserver { _, event -> // TODO: recover the state from saved state registry } ) } } 39 Shibuya.apk #42
lifecycle ▸ Saveable values are disposed on exit composition by default ▸ We can extend the lifecycle ▸ as long as the navigation destination is in the back stack ▸ similar to navGraphViewModels ▸ see: https://youtu.be/V-s4z7B_Gnc?t=874 43 Shibuya.apk #42
▸ Fixing screen orientation doesn’t help ▸ Can’t stop device folding, theme / locale changes, etc… ▸ Stopping con fi g changes ▸ It’s on you, not the system; More code required to handle this ▸ Can’t stop activity recreation for some con fi guration changes 44 ✗ android:screenOrientation="portrait" Shibuya.apk #42 ? android:configChanges="orientation"
Developer option to always dispose activity instance ▸ Activity disposal can happen without enabling this option ▸ ViewModel will lost its data without SavedStateHandle 45 Shibuya.apk #42
than 1MB data size in 1 process ▸ Same as Bundle! ▸ otherwise TransactionTooLargeException 💥 ▸ Avoid saving HUGE objects ▸ Bitmap obviously :) ▸ List containing lots of elements 46 Shibuya.apk #42
webpage on showing the WebView ▸ <input> form values are gone after recreation ▸ Accompanist WebView can save scroll position (0.31.1-alpha) ▸ What if we need to implement a image fi le chooser for <input>…? ▸ Android 11+: no worries with stock Photo Picker, it’s transparent activity! ▸ Android 10 and below: no clue… 49 Shibuya.apk #42