Performance optimization for Android

9,752 views
9,563 views

Published on

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.

Published in: Technology
1 Comment
49 Likes
Statistics
Notes
  • On slide 9, you talk about freeing memory that only the UI uses. Could you give examples of what you mean? Is the Cursor to a Cursor-backed ListView such an element that should be released? Is the ListView
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
9,752
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
366
Comments
1
Likes
49
Embeds 0
No embeds

No notes for slide

Performance optimization for Android

  1. 1. Boutique product development company It is amazing what you can accomplish when you have a client-centric team to deliver outstanding products.
  2. 2. 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 Arslan Anwar | Senior Software Engineer Omer Tanveer | Software Engineer
  3. 3. 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
  4. 4. 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
  5. 5. 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 exactly the same as the regular heap size. Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer Managing Your App's Memory
  6. 6. 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 memory that it currently does not need, then your app even while the user is not using it is constraining the system's overall performance So, as the system runs low on memory, it may kill processes in the LRU cache beginning with the process least recently used, but also giving some consideration toward which processes are most memory intensive. Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  7. 7. 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
  8. 8. 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
  9. 9. 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
  10. 10. 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.
  11. 11. 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_LOW 3. TRIM_MEMORY_RUNNING_CRITICAL 4. TRIM_MEMORY_BACKGROUND 5. TRIM_MEMORY_MODERATE 6. TRIM_MEMORY_COMPLETE Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  12. 12. Optimization in Android TRIM_MEMORY_RUNNING_MODERATE Your 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_LOW Your 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_CRITICAL Your 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
  13. 13. Optimization in Android TRIM_MEMORY_BACKGROUND The 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_MODERATE The 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_COMPLETE The 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
  14. 14. 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
  15. 15. 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
  16. 16. 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
  17. 17. 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
  18. 18. 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
  19. 19. 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
  20. 20. 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
  21. 21. 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
  22. 22. 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
  23. 23. 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
  24. 24. 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
  25. 25. 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
  26. 26. 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
  27. 27. 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
  28. 28. 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
  29. 29. 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
  30. 30. 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
  31. 31. 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
  32. 32. 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
  33. 33. 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); // or View 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
  34. 34. 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
  35. 35. 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
  36. 36. 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
  37. 37. Optimization in Android Optimizing Battery Life Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  38. 38. 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
  39. 39. 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
  40. 40. 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
  41. 41. 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
  42. 42. 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 updates completely if the device is car docked. Conversely, you may choose to maximize your updates while car docked if your background service is updating traffic conditions. Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  43. 43. 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
  44. 44. 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 both waking the device to schedule the update at all? Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  45. 45. 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
  46. 46. 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 connectivity is restored. Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  47. 47. 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
  48. 48. 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
  49. 49. 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
  50. 50. Optimization in Android Threads Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  51. 51. 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
  52. 52. Optimization in Android Manager for Multiple Threads Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  53. 53. 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
  54. 54. 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
  55. 55. 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
  56. 56. 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 times and/or intervals. Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  57. 57. 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
  58. 58. 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
  59. 59. 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
  60. 60. 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
  61. 61. 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
  62. 62. 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
  63. 63. 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
  64. 64. 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
  65. 65. 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
  66. 66. 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
  67. 67. 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 code Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  68. 68. Optimization in Android Best Practices Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  69. 69. 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
  70. 70. 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 flow Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  71. 71. 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
  72. 72. Optimization in Android Questions Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  73. 73. Optimization in Android Thank You Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer
  74. 74. Design Principles Reference Arslan Anwar | Senior Software Engineer , Omer Tanveer | Software Engineer • Best Practices for Performance • Best Practices for Background Jobs • Pure Android

×