Manage Memory

We can design and make our app to make it more memory efficient.

Use services sparingly

  • Do not keep service running unless it's actively performing a job

    Running service makes the process expensive because the RAM used by the service can not be used by anything else or paged out.

  • The best way to limit the lifespan of your service is to use anIntentService

    IntentService finishes itself as soon as it's done handling the intent that started it.

Release memory when our user interface becomes hidden

When the user navigates to a different app and your UI is no longer visible, we should release any resources that are used by only your UI.

  • ImplementonStop()to release activity resources

    It is called when anActivityinstance becomes hidden. We should releaseActivityresources such as a network connection or to unregister broadcast receivers.

    We should not release our UI resources here. This ensures that our UI resources are still available to resume theActivityquickly.

  • Release UI resources when you receiveonTrimMemory(TRIM_MEMORY_UI_HIDDEN)callback

    Implement theonTrimMemory()callback in yourActivityclasses. You receive that callback withTRIM_MEMORY_UI_HIDDENonly when all the UI components of your app process become hidden from the user. And you should free resources that only your UI uses.

Release memory as memory becomes tight

Releasing resources based on the following memory levels delivered byonTrimMemory().

  • TRIM_MEMORY_RUNNING_MODERATE
  • TRIM_MEMORY_RUNNING_LOW
  • TRIM_MEMORY_RUNNING_CRITICAL
  • TRIM_MEMORY_BACKGROUND
  • TRIM_MEMORY_MODERATE
  • TRIM_MEMORY_COMPLETE

Use optimized data containers

  • UseSparseArray,SparseBooleanArray, andLongSparseArray

    SparseArrayis more memory efficient than using aHashMapto map Integers to Objects. Because it avoids auto-boxing keys and its data structure doesn't rely on an extra entry object for each mapping.

    It is slower than a traditionalHashMapwhen holding up to hundreds of items.

Avoid using enums

Enums often ask more than twice as much memory as static constants. We can denote that the annotated element of integer type with@IntDef. It represents a logical type and that its value should be one of the explicitly named constants.

@Retention(SOURCE)
  @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
  public @interface NavigationMode {}
  public static final int NAVIGATION_MODE_STANDARD = 0;
  public static final int NAVIGATION_MODE_LIST = 1;
  public static final int NAVIGATION_MODE_TABS = 2;
  ...
  public abstract void setNavigationMode(@NavigationMode int mode);
  @NavigationMode
  public abstract int getNavigationMode();

By the way, we can also just use enums, then asking ProGuard tool to do above automatically.

Use nano protobufs for serialized data in client-side

Protocol buffers are a language-neutral, platform-neutral and extensible mechanism designed by Google. It is small, fast and simple than XML.

Use ProGuard to strip out any unneeded code

The ProGuard tool can shrinks, optimizes and obfuscates our code. It removes unused code and renaming classes, fields and methods with semantically obscure names.

Use zipalign on your final APK

After app is signed, using zipalign to align the final APK package.

$ zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk

Use multiple processes

This technique must always be used carefully and most apps should not run multiple processes, as it can easily increase—rather than decrease—your RAM footprint if done incorrectly. It is primarily useful to apps that may run significant work in the background as well as the foreground and can manage those operations separately.

An example of when multiple processes may be appropriate is when building a music player that plays music from a service for long period of time. An app like this may be split into two process: one for its UI, and the other for the work that continues running in the background service.

<service android:name=".PlaybackService"
         android:process=":background" />

22 May 2016

results matching ""

    No results matching ""