../android-review

Android Review

Table of contents

What types of process would be killed by system

Ref:

- Process and app lifecycle, developer.android

- Persistent work, developer.android

- Background tasks overview, developer.android

To determine which processes to kill and reclaim memory when the system is low on memory, there are some types to distinguish their level of importance: (from most important to less)

A foreground process;

A visible process;

A service process <30mins;

————————————

A cached process. 🚬

Why WorkManager

Use WorkManager to support long-running workers for persistent work, which can run longer than 10 mins. And use WorkManager to do reliable works, in cases like even if the users navigates off a screen, the app exists, or the device restarts.

Kotlin Coroutines
(Asynchronous work, others eg Java Thread)
This is a concurrency framework, not for persistent work.
They are the standard means of leaving the main thread in Kotlin. They leave memory once the app closes, thus is not guaranteed to finish.
AlarmManagerThis would wakes device from Doze mode. Not efficient in terms of power and resource management. Do not use it for background work.
Foreground servicesThis can put potentially heavy load on device and sometimes have privacy and security implications, thus get many restrictions from the system.
WorkManager provides some convenient APIs to make it simpler to create a foreground service. See here

The Components

Services

Create a started service

🍤 This kind of service must be stopped manually.

Create a bound service and bind to a service

🍤 This kind of service can be stopped by the system once no more binding clients.

i) Extend the Binder class.

when the service need to be accessed across separated processes:

ii) Use a Messenger. This does not require thread-safe.

when the service need to be accessed across separated processes and handle them simultaneously:

iii) Use AIDL. This requires thread-safe.

Broadcasts

BroadcastReceivers are context-registered receivers, ie they would be active as long as their registering context is valid, eg registering within an Activity context or an Application context.

Activities

ContentProvider

Persistent data storage with data sharing across processes. This is more like a manage container, if comparing with Room. See more here (developer.android, Data and file storage overview).

App Resources

Quick note of AAPT2

Ref: developer android, AAPT2

AAPT2 (Android Asset Packaging Tool) is a build tool that Android Studio & Android Gradle Plugin use to compile and package your app’s resources. It supports faster compilation of resources by enabling incremental compilation, where resource processing is separated into two steps:

Quick note for handling large bitmaps

Other than using Glide to load resource efficiently, some methods below are worth to try: (Ref: Handling bitmaps, developer.android)

Note for Android drawing models

Ref: Fix custom-drawing issues, developer.android

Hardware acceleration (enabled by default for target api level ≥14) can be turned off on the level of application / activity / window / view.

Hardware acceleration would surely have optimal invalidation in changing these properties of a view by not redrawing the target view: alpha; x, y, translationX, translationY; scaleX, scaleY; rotation, rotationX, rotationY; pivotX, pivotY.

It is even better for memory efficiency to disable hardware layers when properties changes (animations) are ended.

Tips & tricks for using GPU effectively

Ref: Fix custom-drawing issues.

Note for memory management

Ref: Overview of memory management, developer.android

Ref: Tool of Investigating RAM usage guide in android studio (Inspect your app’s memory usage with Memory Profiler, developer.android. )

Ref: Tool of Inspect app memory from command line - dumpsys (dumpsys, developer.android )

Ref: Tool of View GC events in logcat (View logs with logcat, developer.android )

Ref: Tips for programming practices to reduce app’s memory use (Manage your app’s memory, developer.android)

Ref: Garbage Collection, explained (wiki)

Ref: Debug ART garbage collection (source.android)

Tips for managing app’s memory

Who will reclaim the memory in low memory situations?

Ref: <a rel="noopener" target="_blank" href="https://developer.android.com/topic/performance/memory-management#low-memory_killer">Memory allocation among processes, Low-memory killer. Top one with higher score would be killed first by lmkd.

Ref: Memory allocation among processes, Low-memory killer. Top one with higher score would be killed first by lmkd.

Ref: <a rel="noopener" target="_blank" href="https://developer.android.com/topic/performance/memory-management#memory_pages">Memory allocation among processes. kswapd manipulates on pages to reclaim memory.

Ref: Memory allocation among processes. kswapd manipulates on pages to reclaim memory.

Note for saving UI states

Reference: Save UI states, developer.android

Other References: See Handling the configuration change yourself . DataStore is a modern data storage solution that you should use instead of SharedPreferences. Read the DataStore guide for more information. To learn how to implement saved instance state using onSaveInstanceState, see Saving and restoring transient UI state in the Activity Lifecycle guide.

Prerequisite: storage (local & persistent) vs memory (within the app).

i) ViewModel. Use it to handle configuration changes.

ii) Saved instance states. Use it as backup to handle system-initiated process death.

- Jetpack Compose `rememberSaveable`
- Views  `onSaveInstanceState()`
- ViewModels `SavedStateHandle` 

iii) Local persistence for non-transient needs. Use it to handle process death for complex or large data.

Options for preserving UI state.

Reference: Options for preserving UI state.

Key Point: [Saved instance state] APIs only save data written to it when the Activity is stopped. Writing into it in between this lifecycle state defers the save operation till the next stopped lifecycle event.

Important: The SavedStateHandle only saves data written to it when the Activity is stopped. Writes to SavedStateHandle while the Activity is stopped aren’t saved unless the Activity receives onStart followed by onStop again.

Note: In order for the Android system to restore the state of the views in your activity, each view must have a unique ID, supplied by the android:id attribute.

Note: onSaveInstanceState() is not called when the user explicitly closes the activity or in other cases when finish() is called.

/note/ /Android/