If your application has many time-intensive operations, here are some
tricks to improve the performance and provide a better experience for
your users.
- Operations that can take a long time should run on their own thread
and not in the main (UI) thread. If an operation takes too long while it
runs on the main thread, the Android OS may show an application not
responding (ANR) dialog : from there, the user may choose to wait or to
close your application. This message is not very user-friendly and your
application should never have an occasion to trigger it. In particular,
web service calls to an external API are especially sensitive to this
and should always be on their own thread, since a network slowdown or a
problem on their end can trigger an ANR, blocking the execution of your
application. You can also take advantage of threads to pre-calculate
graphics that are displayed later on on the main thread.
- If your application requires a lot of calls to external APIs, avoid
sending the calls again and again if the wifi and cellular networks are
not available. It is a waste of resources to prepare the whole request,
send it off and wait for a timeout when it is sure to fail. You can pool
the status of the connection regularly, switch to an offline mode if no
network is available, and reactivate it as soon as the network comes
back.
- Take advantage of caching to reduce the impact of expensive
operations. Calculations that are long but for which the result won’t
change or graphics that will be reused can be kept in memory. You can
also cache the result of calls to external APIs to a local database so
you won’t depend on that resource being available at all times. A call
to a local database can be faster, will not use up your users’ data plan
and will work even if the device is offline. On the other hand, you
should plan for a way to refresh that data from time to time, for example
keeping a time and date stamp and refreshing it when it’s getting old.
- Save the current state of your activities to avoid having to
recalculate it when the application is opened again. The data loaded by
your activities or the result of any long-running operation should be
saved when the
onSaveInstanceState
event is raised and restored when the onRestoreInstanceState
event is raised. Since the state is saved with a serializable Bundle
object, the easiest way to manage state is to have a serializable state
object containing all the information needed to restore the activity so
only this object needs to be saved. The information entered by the user
in View controls is already saved automatically by the Android SDK and
does not need to be kept in the state. Remember, the activity state may
be lost when the user leaves your application or rotates the screen, not
only when the user navigates to another activity. - Make sure your layouts are as simple as possible, without
unnecessary layout elements. When the view hierarchy gets too deep, the
UI engine has trouble traversing all the views and calculating the
position of all elements. For example, if you create a custom control
and include it in another layout element, it can add an extra view that
is not necessary to display the UI and that will slightly slow down the
application. You can analyze your view hierarchy to see where your layout
can be flattened with the Hierarchy Viewer tool. The tool can be opened
from Eclipse using the Dump View Hierarchy for UI Automator icon in the DDMS perspective, or launch the standalone tool hierarchyviewer in the <sdk>\tools\ directory.