In this post, I will summarize the rules from two excellent articles on modern (as of 2020) Activity and Fragment lifecycles handling. Both articles were written more than 2 years ago, but In 2020 I’m still working on projects that get this wrong. If you want more details or answers, please read them.
Table of Contents
Activity
In the past, it was generally accepted to do a lot of stuff in Activity’s onPause()
and onResume()
methods. Times have changed and doing so will break your app on multi-window devices where two+ apps are displayed at the same time, but only one of them has focus. The others are started, but put on pause. Unfortunately, I see this mistake often in 2020 as well. Well, the “modern rules” are the following:
Method | Do | Don’t |
onCreate() | Reference / initialize views, inject dependencies, restore data from savedInstanceState, get AAC ViewModel | Register listeners, refresh UI, subscribe to observables, allocate resources, start async flows |
onStart() | Register listeners, refresh UI, subscribe to observables, allocate resources, start async flows | |
onStop() | Unregister listeners, unsubscribe from observables, deallocate resources, stop async flows | |
onSaveInstanceState() | Save to a Bundle internal state that needs to be loaded if the activity is killed, skip views state as they are autosaved. | Don’t assume that the activity will be stopped right after this method call, as it might continue to be active. |
↑ Important ↓ Not important | ||
onResume() | Only initialize camera if required (1) | Register listeners, refresh UI, subscribe to observables, allocate resources, start async flows |
onPause() | Only uninitialize camera if already initialized (1) | Unregister listeners, unsubscribe from observables, deallocate resources, stop async flows |
onDestroy() | Nothing | |
(1) Since Android 10 multiple activities can be resumed simultaneously, so handle the camera carefully.
Fragment
Since 2018 Google pushed Android development in the direction of single-Activity apps with many Fragments for each screen. The navigation between them is handled by the Android Jetpack’s Navigation component.
The fragment lifecycle is quite complex. Let’s simplify it.
Method | Do | Don’t |
onCreate(Bundle) | Inject dependencies, restore data from savedInstanceState, cast activity callbacks, get AAC ViewModel | Reference / initialize views, register listeners, refresh UI, subscribe to observables, allocate resources, start async flows |
onCreateView() | Reference / initialize views | Anything else |
onStart() onStop() onSaveInstanceState() | Same as Activity | Same as Activity |
↑ Important ↓ Not important | ||
onResume() onPause() | Same as Activity | Same as Activity |
Constructor onAttach() onDetach() onDestroyView() onDestroy() any other method | Nothing | |
setRetainInstance() | Do not override, never pass true |
Conclusion
I tried to simplify a quite complex topic into two very simple tables. I could be wrong and as always, I accept constructive criticism.