74
Boutique product development company It is amazing what you can accomplish when you have a client-centric team to deliver outstanding products.

Performance optimization for Android

Embed Size (px)

DESCRIPTION

This document primarily covers micro-optimizations that can improve overall app performance when combined, but it's unlikely that these changes will result in dramatic performance effects. Choosing the right algorithms and data structures should always be your priority, but is outside the scope of this document. You should use the tips in this document as general coding practices that you can incorporate into your habits for general code efficiency. One of the trickiest problems you'll face when micro-optimizing an Android app is that your app is certain to be running on multiple types of hardware. Different versions of the VM running on different processors running at different speeds. It's not even generally the case that you can simply say "device X is a factor F faster/slower than device Y", and scale your results from one device to others. In particular, measurement on the emulator tells you very little about performance on any device. To ensure your app performs well across a wide variety of devices, ensure your code is efficient at all levels and aggressively optimize your performance.

Citation preview

Page 1: Performance optimization for Android

Boutique product development companyIt is amazing what you can accomplish when you have a client-centric team to deliver outstanding products.

Page 2: Performance optimization for Android

Boutique product development companyIt is amazing what you can accomplish when you have a client-centric team to deliver outstanding products.

Performance Optimization For Android Arslan Anwar | Senior Software Engineer Omer Tanveer | Software Engineer

Page 3: Performance optimization for Android

Any developer can write code that a computer can understand. Good programmers write code that humans can understand. - Martin Fowler

Best Practices for Android / Mobile applications

❏ Managing Your App's Memory❏ Improving Layout Performance❏ Optimizing Battery Life❏ Multi Threading❏ Performance Optimization ❏ Resource Optimization

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 4: Performance optimization for Android

Optimization in Android

Managing Your App's Memory

❖ Android application memory limit start from 16MB for a low/normal device

❖ Allocating new objects remains resident in RAM.❖ So the only way to completely release memory from your app is to release

object references you may be holding, making the memory available to the garbage collector.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 5: Performance optimization for Android

Optimization in Android

❖ Each Android-powered device has a different amount of RAM available❖ getMemoryClass() to get an estimate of your app's available heap in

megabytes.❖ Try to avoid largeHeap attribute to "true" in the manifest <application> tag

if possible ❖ It can justify when you have large photo editing app type app❖ Additionally, the large heap size is not the same on all devices and, when

running on devices that have limited RAM, the large heap size may be exactlythe same as the regular heap size.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Managing Your App's Memory

Page 6: Performance optimization for Android

Optimization in Android

Switching Apps

Android keeps processes that are not hosting a foreground ("user visible") app component in a least-recently used (LRU) cache

If your app has a cached process and it retains memorythat it currently does not need, then your app even whilethe user is not using it is constraining the system'soverall performance

So, as the system runs low on memory, it may kill processes in the LRU cache beginning with the processleast recently used, but also giving some considerationtoward which processes are most memory intensive.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 7: Performance optimization for Android

Optimization in Android

Using Services

Do not keep running service unless it's actively performing a job.Also be careful to stop service it when its work is done.

System prefers to always keep the service process in running. Then the RAM used by the service can’t be used by anything else or paged out.

This reduces the number of cached processes that the system can keep in the LRU cache, making app switching less efficient. It can even lead to thrashing in the system when memory is tight and the system can’t maintain enough processes to host all the services currently running.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 8: Performance optimization for Android

Optimization in Android

Using Services (Continued..)

The best way to limit the lifespan of your service is to use an IntentService, which finishes itself as soon as it's done handling the intent that started it.

Leaving a service running when it’s not needed is one of the worst memory-management mistakes an Android app can make.

So don’t be greedy by keeping a service for your app running. Not only will it increase the risk of your app performing poorly due to RAM constraints, but users will discover such misbehaving apps and uninstall them.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 9: Performance optimization for Android

Optimization in Android

Release memory when user interface becomes hidden

When app goes in background or UI hide for a screen, releasing UI resources at this time can significantly increase the system's capacity for cached processes, which has a direct impact on the quality of the user experience.

To be notified when the user exits your UI, implement the onTrimMemory() callback in your Activity classes. You should use this method to listen for the TRIM_MEMORY_UI_HIDDEN level, which indicates your UI is now hidden from view and you should free resources that only your UI uses.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 10: Performance optimization for Android

Optimization in Android

Release memory when user interface becomes hidden

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Add callback for onTrimMemory() callback in your activity. This is distinct from the onStop() callback, which is called when an Activity instance becomes hidden, which occurs even when the user moves to another activity in your app.

We can use onStop() to release activity resources such as a network connection or to unregister broadcast receivers, you usually should not release your UI resources until you receive onTrimMemory(TRIM_MEMORY_UI_HIDDEN).

This ensures that if the user navigates back from another activity in your app, your UI resources are still available to resume the activity quickly.

Page 11: Performance optimization for Android

Optimization in Android

Release memory as memory becomes tight

During any stage of your app's lifecycle, the onTrimMemory() callback also tells you when the overall device memory is getting low. You should respond by further releasing resources based on the following memory levels delivered by onTrimMemory():

1. TRIM_MEMORY_RUNNING_MODERATE 2. TRIM_MEMORY_RUNNING_LOW3. TRIM_MEMORY_RUNNING_CRITICAL 4. TRIM_MEMORY_BACKGROUND5. TRIM_MEMORY_MODERATE6. TRIM_MEMORY_COMPLETE

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 12: Performance optimization for Android

Optimization in Android

TRIM_MEMORY_RUNNING_MODERATEYour app is running and not considered killable, but the device is running low on memory and the system is actively killing processes in the LRU cache.

TRIM_MEMORY_RUNNING_LOWYour app is running and not considered killable, but the device is running much lower on memory so you should release unused resources to improve system performance (which directly impacts your app's performance).

TRIM_MEMORY_RUNNING_CRITICALYour app is still running, but the system has already killed most of the processes in the LRU cache, so you should release all non-critical resources now.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Release memory as memory becomes tight

Page 13: Performance optimization for Android

Optimization in Android

TRIM_MEMORY_BACKGROUNDThe system is running low on memory and your process is near the beginning of the LRU list. Although your app process is not at a high risk of being killed, the system may already be killing processes in the LRU cache.

TRIM_MEMORY_MODERATEThe system is running low on memory and your process is near the middle of the LRU list. If the system becomes further constrained for memory, there's a chance your process will be killed.

TRIM_MEMORY_COMPLETEThe system is running low on memory and your process is one of the first to be killed if the system does not recover memory now. You should release everything that's not critical to resuming your app state.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Release memory as memory becomes tight

Page 14: Performance optimization for Android

Optimization in Android

implements ComponentCallbacks2

public void onTrimMemory(int level) { if (level >= TRIM_MEMORY_MODERATE) { // 60 mCache.evictAll();

} else if (level >= TRIM_MEMORY_BACKGROUND) { // 40 mCache.trimToSize(mCache.size() / 2); } }

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Release memory as memory becomes tight

Page 15: Performance optimization for Android

Optimization in Android

Avoid wasting memory with Bitmaps

❖ When you load a bitmap, keep it in RAM only at the resolution you need for the current device's screen.

❖ Scaling it down if the original bitmap is a higher resolution.

❖ Keep in mind that an increase in bitmap resolution results in a corresponding (increase2) in memory needed, because both the X and Y dimensions increase.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 16: Performance optimization for Android

Optimization in Android

Performance Tips

There are two basic rules for writing efficient code:

● Don't do work that you don't need to do.

● Don't allocate memory if you can avoid it.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 17: Performance optimization for Android

Optimization in Android

Performance Tips (Continued..)

● Avoid Creating Unnecessary Objects

● Use Static Final For Constants

● Avoid Internal Getters/Setters

● Use Enhanced For Loop Syntax

● Consider Package Instead of Private Access with Private Inner Classes

● Avoid Using Floating-Point

● Know and Use the Libraries

● Use Native Methods Carefully

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 18: Performance optimization for Android

Optimization in Android

Avoid Creating Unnecessary Objects

Object creation is never free.

As you allocate more objects in your app, you will force a periodic garbage collection.

● If you have a method returning a string, and you know that its result will always be appended to a StringBuffer anyway, change your signature and implementation so that the function does the append directly, instead of creating a short-lived temporary object.

● When extracting strings from a set of input data, try to return a substring of the original data, instead of creating a copy.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 19: Performance optimization for Android

Optimization in Android

Use Static Final for Constants

static int intVal = 42;static String strVal = "Hello, world!";

static final int intVal = 42;static final String strVal = "Hello, world!";

It's good practice to declare constants static final whenever possible.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 20: Performance optimization for Android

Optimization in Android

Avoid Internal Getters/Setters

It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.

Without a JIT, direct field access is about 3x faster than invoking a trivial getter. With the JIT (where direct field access is as cheap as accessing a local), direct field access is about 7x faster than invoking a trivial getter.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 21: Performance optimization for Android

Optimization in Android

Use Enhanced For Loop Syntax

int sum = 0; for (int i = 0; i < mArray.length; ++i) { sum += mArray[i]; }

int sum = 0;int len = mArray.length;

for (int i = 0; i < len; ++i) { sum += mArray[i]; }

int sum = 0; for (int a : mArray) { sum += a; }

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 22: Performance optimization for Android

Optimization in Android

Avoid Using Floating-Point

As a rule of thumb, floating-point is about 2x slower than integer on Android-powered devices.

In speed terms, there's no difference between float and double on the more modern hardware.

Space-wise, double is 2x larger. As with desktop machines, assuming space isn't an issue, you should prefer double to float.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 23: Performance optimization for Android

Optimization in Android

Know and Use the Libraries

In addition to all the usual reasons to prefer library code over rolling your own, bear in mind that the system is at liberty to replace calls to library methods with hand-coded assembler, which may be better than the best code the JIT can produce for the equivalent Java.

The typical example here is String.indexOf() and related APIs.

System.arraycopy() method is about 9x faster than a hand-coded loop on a Nexus One with the JIT.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 24: Performance optimization for Android

Optimization in Android

Improving Layout Performance

Layouts are a key part of Android applications that directly affect the user experience. If implemented poorly, your layout can lead to a memory hungry application with slow UIs. By optimizing your layouts you will be able to implement smooth scrolling interfaces with a minimum memory footprint. Below is the list of topics we will discuss.

❖ Optimizing Layout Hierarchies

❖ Re-using Layouts with <include/>

❖ Loading Views On Demand

❖ Making ListView Scrolling Smooth

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 25: Performance optimization for Android

Optimization in Android

Re-using Layouts with <include/>

Reusing layouts is particularly powerful as it allows you create reusable complex layouts. For example, a yes/no button panel, or custom progress bar with description text.

It also means that any elements of your application that are common across multiple layouts can be extracted, managed separately, then included in each layout.

So while you can create individual UI components by writing a custom View, you can do it even more easily by re-using a layout file.

● Create a Re-usable Layout● Use the <include> Tag● Use the <merge> Tag

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 26: Performance optimization for Android

Optimization in Android

Create a Re-usable Layout

If you already know the layout that you want to re-use, create a new XML file and define the layout. For example, here's a layout that defines a title bar to be included in each activity (titlebar.xml):

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width=”match_parent” android:layout_height="wrap_content" android:background="@color/titlebar_bg">

<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/gafricalogo" /></FrameLayout>

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 27: Performance optimization for Android

Optimization in Android

Use the <include> Tag

Inside the layout to which you want to add the re-usable component, add the <include/> tag. For example, here's a layout that includes the title bar from above:Here's the layout file:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=”match_parent” android:layout_height=”match_parent”>

<include layout="@layout/titlebar"/>

<TextView android:layout_width=”match_parent” android:layout_height="wrap_content" android:text="@string/hello" android:padding="10dp" /></LinearLayout>

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 28: Performance optimization for Android

Optimization in Android

Use the <include> Tag (Continued..)

You can also override all the layout parameters (any android:layout_* attributes) of the included layout's root view by specifying them in the <include/> tag. For example:

<include android:id=”@+id/news_title” android:layout_width=”match_parent” android:layout_height=”match_parent” layout=”@layout/title”/>

However, if you want to override layout attributes using the <include> tag, you must override both android:layout_height and android:layout_width in order for other layout attributes to take effect.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 29: Performance optimization for Android

Optimization in Android

Use the <merge> Tag

The <merge /> tag helps eliminate redundant view groups in your view hierarchy when including one layout within another.

For example, if your main layout is a vertical LinearLayout in which two consecutive views can be re-used in multiple layouts, then the re-usable layout in which you place the two views requires its own root view.

However, using another LinearLayout as the root for the re-usable layout would result in a vertical LinearLayout inside a vertical LinearLayout.

The nested LinearLayout serves no real purpose other than to slow down your UI performance.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 30: Performance optimization for Android

Optimization in Android

Use the <merge> Tag (Continued..)

To avoid including such a redundant view group, you can instead use the <merge> element as the root view for the re-usable layout. For example:

<merge xmlns:android="http://schemas.android.com/apk/res/android"> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/add"/> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/delete"/></merge>

Now, when you include this layout in another layout (using the <include/> tag), the system ignores the <merge> element and places the two buttons directly in the layout, in place of the <include/> tag.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 31: Performance optimization for Android

Optimization in Android

Loading Views on Demand

Sometimes your layout might require complex views that are rarely used.

Whether they are item details, progress indicators, or undo messages, you can reduce memory usage and speed up rendering by loading the views only when they are needed.

● Define a ViewStub● Load the ViewStub Layout

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 32: Performance optimization for Android

Optimization in Android

Define a ViewStub

ViewStub is a lightweight view with no dimension and doesn’t draw anything or participate in the layout.

As such, it's cheap to inflate and cheap to leave in a view hierarchy. Each ViewStub simply needs to include the android:layout attribute to specify the layout to inflate.

The following ViewStub is for a translucent progress bar overlay. It should be visible only when new items are being imported into the application.

<ViewStub android:id="@+id/stub_import" android:inflatedId="@+id/panel_import" android:layout="@layout/progress_overlay" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" />

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 33: Performance optimization for Android

Optimization in Android

Load the ViewStub Layout

When you want to load the layout specified by the ViewStub, either set it visible by calling setVisibility(View.VISIBLE) or call inflate()

((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);// orView importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();

The inflate() method returns the inflated View once complete. so you don't need to call findViewById() if you need to interact with the layout.

Once visible/inflated, the ViewStub element is no longer part of the view hierarchy. It is replaced by the inflated layout and the ID for the root view of that layout is the one specified by the android:inflatedId attribute of the ViewStub. (The ID android:id specified for the ViewStub is valid only until the ViewStub layout is visible/inflated.)

Note: One drawback of ViewStub is that it doesn’t currently support the <merge/> tag in the layouts to be inflated.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 34: Performance optimization for Android

Optimization in Android

Making ListView Scrolling Smooth

The key to a smoothly scrolling ListView is to keep the application’s main thread (the UI thread) free from heavy processing. Ensure you do any disk access, network access, or SQL access in a separate thread.

● Use a Background Thread

● Hold View Objects in a View Holder

● Avoid heavy operations

● Efficiently load bitmaps

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 35: Performance optimization for Android

Optimization in Android

Use a Background Thread

// Using an AsyncTask to load the slow images in a background thread new AsyncTask<ViewHolder, Void, Bitmap>() { private ViewHolder v;

@Override protected Bitmap doInBackground(ViewHolder... params) { v = params[0]; return mFakeImageLoader.getImage(); }

@Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); if (v.position == position) { // If this item hasn't been recycled already, hide the // progress and set and show the image v.progress.setVisibility(View.GONE); v.icon.setVisibility(View.VISIBLE); v.icon.setImageBitmap(result); } }}.execute(holder);

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 36: Performance optimization for Android

Optimization in Android

Hold View Objects in a View Holder

static class ViewHolder { TextView text; TextView timestamp; ImageView icon; ProgressBar progress; int position;}Then populate the ViewHolder and store it inside the layout.

ViewHolder holder = new ViewHolder();holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);holder.text = (TextView) convertView.findViewById(R.id.listitem_text);holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);convertView.setTag(holder);

Now you can easily access each view without the need for the look-up, saving valuable processor cycles.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 37: Performance optimization for Android

Optimization in Android

Optimizing Battery Life

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 38: Performance optimization for Android

Optimization in Android

Optimizing Battery Life

For your app to be a good citizen, it should seek to limit its impact on the battery life of its host device. By taking steps such as disabling background service updates when you lose connectivity, or reducing the rate of such updates when the battery level is low, you can ensure that the impact of your app on battery life is minimized, without compromising the user experience.

❖ Monitoring the Battery Level and Charging State

❖ Determining and Monitoring the Docking State and Type

❖ Determining and Monitoring the Connectivity Status

❖ Manipulating Broadcast Receivers On Demand

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 39: Performance optimization for Android

Optimization in Android

Monitoring the Battery Level and Charging State

If you are requesting for updates or synchronizing your data then frequency of your background task should be based on battery level and charging state of the device.

❖ Determine the Current Charging State➢ Monitor Changes in Charging State

■ ACTION_POWER_CONNECTED■ ACTION_POWER_DISCONNECTED

➢ If charing■ AC Charge ( Update after 5 mint)■ USB Charger ( Update after 15 mint)

➢ If not connected■ Update after 1 hour ( Still need optimization )

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 40: Performance optimization for Android

Optimization in Android

Monitoring the Battery Level and Charging State

You may choose to reduce the rate of your background updates if the battery charge is below a certain level.

❖ Determine the Current Battery Level➢ Monitor Changes in Charging State

■ ACTION_BATTERY_LOW■ ACTION_BATTERY_OKAY

➢ Or you may want to check current level ■ if battery level > 50 ( Update after 30 mint ) ■ if battery level < 20 ( don’t update )

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 41: Performance optimization for Android

Optimization in Android

Monitoring the Battery Level and Charging State

Generally speaking, the impact of constantly monitoring the battery level has a greater impact on the battery than your app's normal behavior, so it's good practice to only monitor significant changes in battery level—specifically when the device enters or exits a low battery state.

It is generally good practice to disable all your background updates when the battery is critically low. It doesn't matter how fresh your data is if the phone turns itself off before you can make use of it.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 42: Performance optimization for Android

Optimization in Android

Determining and Monitoring the Docking State and Type

Android devices can be docked into several different kinds of docks. These include car or home docks and digital versus analog docks. The dock-state is typically closely linked to the charging state as many docks provide power to docked devices.

You may choose to increase the update frequency of a sports center app when it's in the desktop dock, or disable your updatescompletely if the device is car docked.Conversely, you may choose to maximize your updates while car docked if your background service is updating trafficconditions.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 43: Performance optimization for Android

Optimization in Android

Determining and Monitoring the Docking State and Type

❖ Determine the Current Docking State➢ The dock state is also broadcast as a sticky Intent, allowing you to

query if the device is docked or not, and if so, in which kind of dock.

❖ Determine the Current Dock Type➢ Car ➢ Desk➢ Low-End (Analog) Desk➢ High-End (Digital) Desk

❖ Monitor for Changes in the Dock State or Type➢ ACTION_DOCK_EVENT

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 44: Performance optimization for Android

Optimization in Android

Determining and Monitoring the Connectivity Status

Some of the most common uses for repeating alarms and background services is to schedule regular updates of application data from Internet resources, cache data, or execute long running downloads.

But if you aren't connected to the Internet, or the connection is too slow to complete your download, why bothwaking the device to schedule theupdate at all?

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 45: Performance optimization for Android

Optimization in Android

Determining and Monitoring the Connectivity Status

❖ Determine if You Have an Internet Connection➢ There's no need to schedule an update based on an Internet

resource if you aren't connected to the Internet.❖ Determine the Type of your Internet Connection

➢ Device connectivity can be provided by mobile data, WiMAX, Wi-Fi, and ethernet connections.

➢ You can alter your refresh rate based on the bandwidth available.➢ Update rate should be lower when on mobile connections. It cost

more to user.➢ Downloads of significant size should be suspended until you have

a Wi-Fi connection.❖ Monitor for Changes in the Dock State or Type

➢ CONNECTIVITY_CHANGE

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 46: Performance optimization for Android

Optimization in Android

Determining and Monitoring the Connectivity Status

Changes to a device's connectivity can be very frequent—this broadcast is triggered every time you move between mobile data and Wi-Fi. As a result, it's good practice to monitor this broadcast only when you've previously suspended updates or downloads in order to resume them.

It's generally sufficient to simply check for Internet connectivity before beginning an update and, should there be none, suspend further updates until connectivityis restored.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 47: Performance optimization for Android

Optimization in Android

Manipulating Broadcast Receivers On Demand

When register a broadcast for specific side-effect of this approach is that your app will wake the device each time any of these receivers is triggered—potentially much more frequently than required.

A better approach is to disable or enable the broadcast receivers at runtime. That way you can use the receivers you declared in the manifest as passive alarms that are triggered by system events only when necessary.

Example: If you are requesting for update from network when device connect to charger. Then you should disable this receiver when network is not connected.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 48: Performance optimization for Android

Optimization in Android

Manipulating Broadcast Receivers On Demand

ComponentName receiver = new ComponentName(context, myReceiver.class);PackageManager pm = context.getPackageManager();pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

Using this technique, if you determine that connectivity has been lost, you can disable all of your receivers except the connectivity-change receiver. Conversely, once you are connected you can stop listening for connectivity changes and simply check to see if you're online immediately before performing an update and rescheduling a recurring update alarm.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 49: Performance optimization for Android

Optimization in Android

Sending Operations to Multiple Threads

The speed and efficiency of a long-running, data-intensive operation often improves when you split it into smaller operations running on multiple threads. On a device that has a CPU with multiple processors (cores), the system can run the threads in parallel, rather than making each sub-operation wait for a chance to run.

For example, decoding multiple image files in order to display them on a thumbnail screen runs substantially faster when you do each decode on a separate thread.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 50: Performance optimization for Android

Optimization in Android

Threads

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 51: Performance optimization for Android

Optimization in Android

Running a Thread

❖ In a Thread run() method use Process.setThreadPriority() with THREAD_PRIORITY_BACKGROUND. This approach reduces resource competition between the Runnable object's thread and the UI thread.

❖ If you don't set the thread to a lower priority this way, then the thread could still slow down your app because it operates at the same priority as the UI thread by default.

❖ Stores the current Thread reference in your app, so that you want to interrupt the Thread later on. e.g On network failure you can cancel that thread operation.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 52: Performance optimization for Android

Optimization in Android

Manager for Multiple Threads

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 53: Performance optimization for Android

Optimization in Android

Manager for Multiple Threads

❖ To automatically run tasks as resources become available, or to allow multiple tasks to run at the same time (or both), you need to provide a managed collection of threads. To do this, use an instance of ThreadPoolExecutor, which runs a task from a queue when a thread in its pool becomes free. To run a task, all you have to do is add it to the queue.

➢ You can have a reference of threads. e.g get current thread refrance

■ mPhotoTask.setImageDecodeThread(Thread.currentThread());

➢ You may want to discard old threads when adding a new one.

➢ You can peorities your threads

➢ You can discard any or all the thread if require.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 54: Performance optimization for Android

Optimization in Android

Communicating with the UI Thread

❖ Every app has its own special thread that runs UI objects such as View objects; this thread is called the UI thread. Only objects running on the UI thread have access to other objects on that thread. Because tasks that you run on a thread from a thread pool aren't running on your UI thread, they don't have access to UI objects.

❖ To move data from a background thread to the UI thread, use a Handler that's running on the UI thread.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 55: Performance optimization for Android

Optimization in Android

Communicating with the UI Thread

// Defines a Handler object that's attached to the UI thread mHandler = new Handler(Looper.getMainLooper()) {

@Override public void handleMessage(Message inputMessage) { // Gets the image task from the incoming Message object. PhotoTask photoTask = (PhotoTask) inputMessage.obj; ... }

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 56: Performance optimization for Android

Optimization in Android

AlarmManager Repeating tasks

Alarms (based on the AlarmManager class) give you a way to perform time-based operations outside the lifetime of your application. For example, you could use an alarm to initiate a long-running operation, such as starting a service once a day to download a weather forecast.

❖ They let you fire Intents at set timesand/or intervals.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 57: Performance optimization for Android

Optimization in Android

AlarmManager Repeating tasks

❖ You can use them in conjunction with broadcast receivers to start services and perform other operations.

❖ They operate outside of your application, so you can use them to trigger events or actions even when your app is not running, and even if the device itself is asleep.

❖ They help you to minimize your app's resource requirements. You can schedule operations without relying on timers or continuously running background services.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 58: Performance optimization for Android

Optimization in Android

Choose an alarm type

❖ ELAPSED_REALTIME—Fires the pending intent based on the amount of time since the device was booted, but doesn't wake up the device. The elapsed time includes any time during which the device was asleep.

❖ ELAPSED_REALTIME_WAKEUP—Wakes up the device and fires the pending intent after the specified length of time has elapsed since device boot.

❖ RTC—Fires the pending intent at the specified time but does not wake up the device.

❖ RTC_WAKEUP—Wakes up the device to fire the pending intent at the specified time.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 59: Performance optimization for Android

Optimization in Android

Example Code

private AlarmManager alarmMgr;

private PendingIntent alarmIntent;

...

alarmMgr = (AlarmManager)context.getSystemService(Context.

ALARM_SERVICE);

Intent intent = new Intent(context, AlarmReceiver.class);

alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,

SystemClock.elapsedRealtime() +

60 * 1000, alarmIntent);

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 60: Performance optimization for Android

Optimization in Android

AlarmManager operations

❖ Cancel Alaram

// If the alarm has been set, cancel it.

if (alarmMgr!= null) {

alarmMgr.cancel(alarmIntent);

❖ Start an Alarm When the Device Boots

public class SampleBootReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {

// Set the alarm here.

}

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 61: Performance optimization for Android

Optimization in Android

Keeping Your App Responsive

In Android, the system guards against applications that are insufficiently responsive for a period of time by displaying a dialog that says your app has stopped responding, such as the dialog in Figure.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 62: Performance optimization for Android

Optimization in Android

What Triggers ANR?

In Android, application responsiveness is monitored by the Activity Manager and Window Manager system services. Android will display the ANR dialog when:❖ No response to an input event (such as key press or screen touch events)

within 5 seconds.➢ an application blocks on some I/O operation➢ app is working some network task on UI thread ➢ app spends too much time building an elaborate in-memory structure➢ app sepnd computing the next move in a game on the UI thread

❖ A BroadcastReceiver hasn't finished executing within 10 seconds.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 63: Performance optimization for Android

Optimization in Android

How to Avoid ANRs

❖ On UI thread do as little work as possible. ❖ Process.setThreadPriority() else Thread will be equal to UI thread❖ If your application is doing work in the background in response to user

input, show that progress is being made (such as with a ProgressBar in your UI).

❖ For games specifically, do calculations for moves in a worker thread.❖ Use performance tools such as Systrace and Traceview to determine

bottlenecks in your app's responsiveness.❖ If your application has a time-consuming initial setup phase, consider

showing a splash screen or rendering the main view as quickly as possible, indicate that loading is in progress and fill the information asynchronously.

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 64: Performance optimization for Android

Optimization in Android

Keeping the Device Awake

To avoid draining the battery, an Android device that is left idle quickly falls asleep. However, there are times when an application needs to wake up the screen or the CPU and keep it awake to complete some work.

The approach you take depends on the needs of your app. However, a general rule of thumb is that you should use the most lightweight approach possible for your app, to minimize your app's impact on system resources

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 65: Performance optimization for Android

Optimization in Android

Keep the Screen On

Certain apps need to keep the screen turned on, such as games or movie apps. The best way to do this is to use the FLAG_KEEP_SCREEN_ON in your activity (and only in an activity, never in a service or other app component)

❖ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); in your activity onCreate

❖ android:keepScreenOn="true" in your layout ❖ It doesn't require special permission❖ Platform correctly manages the user moving between applications❖ You can use clearFlags(): to remove this

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 66: Performance optimization for Android

Optimization in Android

Keep the CPU On

If you need to keep the CPU running in order to complete some work before the device goes to sleep, you can use a Power Manager system service feature called wake locks. Creating and holding wake locks can have a dramatic impact on the host device's battery life. Thus you should use wake locks only when strictly necessary and hold them for as short a time as possible.

❖ <uses-permission android:name="android.permission.WAKE_LOCK" />❖ PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);

❖ Wakelock wakeLock = powerManager.newWakeLock(PowerManager.

PARTIAL_WAKE_LOCK,

❖ "MyWakelockTag");

❖ wakeLock.acquire();

❖ wakelock.release().

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 67: Performance optimization for Android

Optimization in Android

Tips For Layout

❖ Put margins , padding in values/dimens.xml file

❖ User Nine Patch Image

❖ Reuse images

❖ Avoid hardcode sizes

❖ <Include layouts>

❖ Name layout that can easily access in activity

❖ For multiple screens extract dynamic information from layout and only

change these information instead of repeating files

❖ Use JPG image if transparency is not required in image.

❖ Use layout_weight

❖ Use styles / Themes for you application instead of duplicating codeArslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 68: Performance optimization for Android

Optimization in Android

Best Practices

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 69: Performance optimization for Android

Optimization in Android

Tips For Bitmap

❖ Scale down bitmaps

❖ Try to create drawable via xml if possible

❖ Recycle bitmap after using

❖ User SoftReference for bitmaps

❖ Cache Bitmaps instead of download again or load again

❖ Track memory size and discard old bitmaps

❖ User Nine Patch Image

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 70: Performance optimization for Android

Optimization in Android

Tips For Activity / Fragments

❖ Create Base activity that cover all your common /repeating functionality

❖ Divide functionality into methods as much as possible

❖ Class must not be too long. Remember SOLID principles

❖ Apply design patterns wherever possible.

❖ DO NOT use meaningless variables

❖ private method can have long name but public method should have small

name

❖ Methods must focus on single task

❖ Method should throw exceptions instead of catch and do nothing

❖ Don’t catch all exceptions. Only catch exception where you have

alternative flowArslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 71: Performance optimization for Android

Optimization in Android

Tips For Activity / Fragments

❖ Remove listeners , release bitmap when destroying activity

❖ Resolve dependency using state/strategy design patterns methods

❖ Use TAG for fragments and reload on demand

❖ Deal with interfaces instead of classes

❖ Write code as a library project

❖ Minimize code complexity by avoiding if else paths

❖ Deal with DB carefully to avoid open close issues

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 72: Performance optimization for Android

Optimization in Android

Questions

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer

Page 73: Performance optimization for Android

Optimization in Android

Thank You

Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer