Best Practices for Performance
- Build an app that is smooth, responsive, and uses a little battery as possible.
1 Performance Tips
- Optimize app preformance.
- Improve responsiveness and battery efficiency.
- Two basic rules :
- Don’t do work that you don’t need to do.
- Don’t allocate memory if you can avoid it.
1.1 Avoid Creating Unnecessary Objects
1.2 Perfer Static Over Virtual
1.3 Use Static Final For Constants
1.4 Use Enhanced For Loop Syntax
1.5 Consider Package
1.6 Avoid Using Floating-Point
1.7 Konw and Use the Libraries
1.8 Use Native Methods Carefully
1.9 Performace Myths
1.10 Always Measure
2 Improving Layout Performance
- Layout performance and UI repsonsiveness.
- Layouts effect UX.
- Avoid memory hungry.
- Smooth scrolling interfaces.
2.1 Optimizing Layout Hierarchies
- By SDK tool optimize layout.
2.1.1 Inspect Your Layout
- Android Studio/VAS/ADV/Hierarchy viewer.
2.1.2 Revise Your Layout
- User
RelativeLayout
2.1.3 Use Lint
- Compound drawables
- Merge root frame
- Useless leaf
- Useless parent
- Deep layouts
- Lint is integrated into Android Studio.
- File>Settings>Project Settings to manage inspection profiles and configure inspections with AS.
2.2 Re-using Layouts with
- Efficiently re-use layouts, use
<include/>
or<merge/>
tags to embed another layout inside current layout.
2.2.1 Create a Re-usable Layout
- Define a new layout such as a title bar layout.
tools:showIn
is a special attribute that is removed during compilation and used, only shows at design-time in Android Studio.
2.2.2 Use the Tag
2.2.3 Use the Tag
- The tag helps eliminate redundant view groups in view hierarchy when including one layout within another.
- When you use
tag, the system ingnores the element.
2.3 Delayed Loading of views
- Complex view rarely used.
- Reduce memory usage and delay loading.
- ViewStub
2.3.1 Define a ViewStub
- ViewStub is lightweight view, and simply needs
android:layout
to inflate.
2.3.2 Load the ViewStub Layout
findViewById(R.id.stub)
to setVisibility, inflate;- One drawback is it doesn’t support
tag.
2.4 Making ListView Scrolling Smooth
- Smoothly scrolling
ListView
. - Keep UI thread free from heavy processing.
- Any disk, network or SQL access in a separate thread.
- StrictMode tests the status of apps.
2.4.1 Use a Bg Thread
- @WorkerThread
- Using
AsyncTask
2.4.2 Hold View Objects in a View Holder
- Using
ViewHolder
avoidsfindViewById
frequently. - A
ViewHolder
object stores views inside the tag field of the layout.
3 Optimizing Battery Life
- Minimize power.
- Perform power-hungry tasks at proper intervals.
3.1 Optimizing for Doze and App Standby
3.2 Monitoring the Battery Level and Charging State
3.3 Determining and Monitoring the Docking State and Type
3.4 Determining and Motnitoring the Connectivity Status
4 Sending Operations to Multiple Threads
- Long-running operations by dispatching work to multiple threads.
- The speed and efficiency of a long-running, data-intensive operations need to improve.
- Split into smaller operations running on multiple threads.
- A CPU with multiple processors(cores) makes the system running threads in parallel not waiting.
- Use multiple threads and a thread pool object, conmmnunicate between UI thread and others.
4.1 Specifying the Code to Run on a Thread
- Run a seperate Thread.
- Implement the Runnable interface.
- Runnable Object’s thread passes a Runnable attaching another thread.
- One or more Runnable objects that perform a particular operation are sometimes called a
task
. - Basic class:
HandlerThread, AsyncTask, IntentService
,ThreadPoolExecutor
.
4.1.1 Define a Class that Implements Runnable
4.1.2 Implement the run() Method
- Implement
Runnable.run()
, not directly modify UI objects. - At the begining of the
run()
method, set the thread bg priority by callingProcess.setThreadPriority()
withTHREAD_PRIORITY_BACKGROUND
to reduce res competition between the thread and UI thread. -
Thread.currentThread()
to store a reference in theRunnable()
itself.// Moves the current Thread into the background android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND); ... /* * Stores the current Thread in the PhotoTask instance, * so that the instance * can interrupt the Thread. */ mPhotoTask.setImageDecodeThread(Thread.currentThread());
4.2 Creating a Manager for Multiple Threads
- Manage a thread pool and a Runnable queue.
- ThreadPoolExecutor
IntentService
run a task repeatly, but you only need one execution running at a time.- ‘ThreadPoolExecutor’ automatically run tasks, and run multiple tasks at the same time.
- Access (static) variables need
thread-saft
, addsynchronized
block.
4.2.1 Define the Thread Pool Class
- Use static variables for thread pools,a signle static instance.
- Private constructor ensures it is a singleton.
- Start tasks
threadPool.execute();
- Init
handler
and implementhandleMessage()
to handle message.
4.2.2 Determine the Thread Pool Parameters
- Init pool and maximum pool size.
- Keep alive time and time unit.
- A queue of tasks,
LinkdBlockingQueue<Runnable>
.
4.2.3 Create a Pool of Threads
new ThreadPoolExecutor(init pool size, max pool size, alive time, queue)
4.3 Running Code on a Thread Pool Thread
- Run a Runnable on a thread from the thread pool.
4.3.1 Run a Task on a Thread in the Thread Pool
- Start a task by
ThreadPoolExecutor.execute(Runnable)
4.3.2 Interrupt Running Code
- Stop a task before, store a handle to the task’s thread.
Thread.currentThread()
- Stop a task by calling
Thread.interrupt()
. Check the thread has been interruptedThread.interrupted()
.
4.4 Communicating with the UI Thread
- Communicate from a thread in the thread pool to the UI thread.
4.4.1 Define a Handler on the UI Thread
- Handler is part of the Android system’s framework for managing threads.
new Handler(Looper)
is connected to a new thread, a existing thread, or UI thread.- Looper
- Override
handleMessage()
4.4.2 Move Data from a Task to the UI Thread
Move data from a bg thread to UI thread, and send a message containting the status to the Handler
.
- Store data in the task object
- Send status up the object hierarchy
- Move data to the UI,
Handler.obtanMessage(state)
, andUIHandler
handle message.
5 Keeping Your app Responsive
- UI doesn’t lock-up and ANR.
- For significant periods, feel bad, and the worst thing is the system displays “Application Not Responding” (ANR) dialog.
5.1 What Triggers ANR?
- App cannot respond to user input, then the system displays an ANR.
- For example, on UI thread operate I/O or network access, database, spend too much time building or a big compitations such as resizing bitmaps, an asynchronous request.
- Create a worker thread to do most of the work.
- Application responsiveness is monitored by the ActivityManager and WindowManager system services.
- Within 5s no response.
- Within 10s a BroadcastReceiver hasn’t finished executing.
5.2 How to Avoid ANRs
- On UI Thread run as little work as possible. Activities set up in key lift-cycle methods
onCreate()
andonResume()
. - The most effective way is that use the
AsyncTask
class ; -
Use
Thread
,HandlerThread
to “background” priority and do not callThread.wait()/sleep()
. - On
BroadcastReceiver
, constraint : small, discrete work in bg such as saving a setting or registering aNotification
. IntentService
do intensive tasks, long running action.- Another common issue with
BroadcastReceiver
objects occurs when they execute too frequently.
5.3 Reinforce Responsiveness
- The threshold beyond 100 ~ 200ms.
- In bg do work, show the progress.
- For games, do calculations for moves in worker thread.
- A time-consuming initial setup phase, show a splash screen.
- Use performace tools such as
Systrace
andTraceView
.
6 JNI Tips
- Use Java Native Interface with the Android NDK.
7 SMP Primer for Android
- On symmetric multiprocessor systems.