Tip 1 - Fragment’s view vs instance lifecycles
Use Fragment’s view lifecycle when observing lifedata in Fragments. This allows releasing resources when the view is gone but Fragment’s instance is still alive.
When the user navigates away from a fragment but the fragment is still in backstack, Android will keep the instance of the fragment but will kill the view to save resources. When the user goes back to the fragment onCreateView
is called and we create a new view for the same fragment object we had before.
-
LiveData observers - if this is done in
onCreateView
-
RV adapter keeps references to ViewHolder instances and those keep references to the inflated views. When we have a reference to the adapter all ViewHolder instances and View instances remain in memory when the user navigates away from the fragment. This gives a benefit of not having to inflate views again when the user comes back but that comes with a cost of keeping them in memory. So, just be aware of this and use it to your advantage.
Tip 2 - Minimize requestLayout()
calls on RecyclerView
- Measure it by extending RV and counting
requestLayout()
calls - ImageView
- use fixed width, height if you can and put a placeholder with the same width height. See https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/ImageView.java#585
- use AspectRatioImageView
- TextView: TBD
- Use
recyclerView.setHasFixedSize(true)
to prevent remeasuring when item views change.
Tip 3 - LiveData postValue()
vs value=
postValue()
is for posting LiveData value from a different threadpostValue()
is much slower (more than 100ms vs less than 10ms) therefore usevalue=
if possible
Tip 4 - Reading from Room database
- Observing values is slower than getting them. Use get, render the view than observe the value for changes.
Tip 5 - Image loading with Glide
- Use
placeholder()
to prevent asetImageDrawable()
call with anull
value, which causes remeasurement - Make sure placeholder size is equal to the loaded image. Resize the loaded image to keep the sizes the same
Tip 6 - Using android.text.format.DateUtils
- The first call to
DateUtils.getRelativeDateTimeString
takes about 400ms in average, subsequent calls take 2-8ms - Make a dummy call
getRelativeDateTimeString
on a background thread to avoid spending that time when loading a screen
Tip 7 - Use SparseArray or ArrayMap for performance
- Boxing: int -> Integer
- Unboxing: Integer -> int
- Source