Optimising Android application before release

JavaAndroidOptimization

Java Problem Overview


I'm in a "special" situation about efficiency of my program. Now I'm at a phase where I need to improve the performance of the application and reduce battery consumption.

Before the question:

Now, I'm curious to know about other developers' special fixes which they have used to optimise their own applications. Stuff that users may never recognise or pay attention to. However, the fixes will either increase the battery life or help improve maintenance of the application.

So, what's your unique optimizing trick(s)?

I'm in a particular situation where I'm really looking for knowledge and I think this will be a great opportunity to share developers knowledge about a situation they've all been in.

Please, vote up great answers as that will encourage great developers to share their knowledge.

Java Solutions


Solution 1 - Java

At some point you are going to get to the point where using known tricks will hit their limits. The best thing to do at this point is profile your code and see what areas are the bottle-necks based on your specific requirements.

Investigating RAM usage using MAT and Using Traceview: an article on how to use the tools to profile your application.

Solution 2 - Java

Track and squash allocations. The more you allocate, the more often the garbage collector will need to run, stopping your process from doing anything else for relatively long periods of time, such as 100ms or so.

The best tool I know for this is the Allocation Tracker included in DDMS.

Not only GC can have an impact on the user experience, but superfluous allocations and GC do consume some computing resources.

Here's an example and a small trick. In my app, I have a clock which shows the current (audio) time, including tenth of seconds. This is updated often. And TextView performs allocations internally whenever you call setText() with a CharSequence. But it doesn't allocate anything with the setText(char[] text, int start, int len) variant. This isn't documented, and no one answered when I asked about it.

There are many ones like this. And this is one of the reasons why my app contains 50% native code (but there are other reasons).

Apart from this, I can recommend that you experiment with ProGuard. It performs several optimization passes, and logs such informations as unused methods within the project, which can help you removing leftovers in your code.

Solution 3 - Java

If your app will have a lot of screen time, use black wherever you can. That will reduce the battery consumption of the worst part of the device: the screen, specially in the AMOLED phones and tablets.

Solution 4 - Java

For applications with multiple activities, check you are not restarting activities that just need to be brought to the front by using the appropriate Intent flags. Check that your heap is under control, and that unnecessary views, bindings and contexts aren't being created.

I find the best tool for showing you all these as the app runs is:

adb shell dumpsys meminfo 'your apps package name'

Solution 5 - Java

When using SQLlite, put special attention on indexes. Don't assume anything. I got tremendous speedups in Zwitscher, when I put indexes on columns commonly used for search.

Solution 6 - Java

A few tips that can help you optimize your app in terms of UI:

  • use convertView for list adapters - it would be very expensive if you create a new view inside Adapter.getView() as this routine is called for every position in the list. Using convertView lets you reuse the already created view. Good example (together with the use of ViewHolder) can be found in ApiDemos.

  • It might happen that your layouts are not fully optimized and can be improved (for instance by using merging or removing parents). Android tool layoutopt will find such a situation for you. It can be used with HierarchyViewer for inspecting individual views. More info here.

  • remove the background drawable - Android framework used to have (does it still have?) a problem with detecting what views should be drawn. There is a chance that your (default) background drawable will be drawn only to be subsequently hidden by your opaque UI. To get rid of this wasteful drawing simply remove background drawable.

It can be done using a custom style

<resources>
    <style name="Theme.NoBackground" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
    </style>
</resources>

A few tips that can help you optimize your app in terms of battery usage:

  • check networking type and wait until user gets in the area with wifi or 3G (and not roaming) and only then allow him to use connection

  • use gzip for textual data whenever possible to speed up download and parsing

  • recycle complex java objects such as XmlPullParserFactory/BitmapFactory/StringBuilder/Matcher etc.

For more battery tricks see Coding for Life - Battery Life, That Is.

Solution 7 - Java

Something to think about: DO NOT overuse String, for example in a huge loop. This will create a lot of String objects that have to be GC'ed. The "Bad coding" example will produce 2 string objects every loop. Next example will produce only one final String and a single stringbuilder. This makes a huge difference when optimizing huge loops for speed. I used stringbuilder a lot when making my Wordlist Pro Android app, and it got really speedy when going through 270000 words in no time.

    //Bad coding:
    String s = "";
    for(int i=0;i<999999;i++){
        s = "Number=";
        s = s + i;
        System.out.println(s);
    }

    //Better coding
    final String txt = "Number=";
    StringBuilder sb = new StringBuilder();
    for(int i=0;i < 999999;i++){
        sb.setLength(0);
        sb.append(txt);
        sb.append(i);
        System.out.println(sb);
    }

I wrote a more extended blogpost about the matter. read here

Solution 8 - Java

I guess using "final" variables everywhere where it's possible could also improve execution speed.

Solution 9 - Java

Optimize your PNG pictures with tools like OptiPNG and PNGCrush to shave off some (kilo)bytes from APK size. Image optimization tips for websites apply here too: use appropriate picture formats, play with JPG compression, consider using binary transparencies instead of 8-bit transparencies etc.

If you ship big PNGs with alpha channel, you can trade some APK size for startup speed and use separate JPGs for RGB and A channels.

If you're making HTTP connections, check that your HTTP client utilizes content compression. If it caches received HTTP responses, check that it understands and uses caching-related HTTP headers correctly.

Solution 10 - Java

If you have network operations try re-using same httpclient instance. Avoid using regular expressions.

Solution 11 - Java

Try using DDMS to track all the threads running in the system. For example i have noticed that I was using webview to display html content, i noticed that it creates few threads for cookie management session management etc..which increased my memory foot print. So unless you have a serious need for displaying complex html try using normal utility class "Html" in android to display html content. This might be useful for people who are displaying Eula since eula typicall contains html text.

If you have to do network operations try using AndroidHttpClient if you are beginner, it has got some good capabilities for Caching SSL sessions and all it really helps in improving your performance. Always set your socket connection timeouts to something around 60 seconds or some finite values because infinite timeouts can cause deadlocks especially if you drop your connection during ssl handshake.

Solution 12 - Java

Use the Android Resource Tracker to find unused resources in your project that can be deleted.

Solution 13 - Java

Avoid using XPath if you can parse your XML input by using string manipulation routines to get the text between the tags. I have tested and can confirm a 10x improvement in this case, on a 50000 items data set, on a HTC Desire.

Solution 14 - Java

I know I am joining a bit later to this conversation but it would be perfect to have a lot of good tips in one place, so I hope this thread will be alive and updated pretty often. My tips:

  • Don't block UI thread with expensive jobs, user will leave if there is no response from app (use AsyncThreads).
  • Use the LINT, new tool which scans Android project sources for potential bugs.

..will be updated..

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWroclaiView Question on Stackoverflow
Solution 1 - JavaunholysamplerView Answer on Stackoverflow
Solution 2 - JavaoliviergView Answer on Stackoverflow
Solution 3 - JavaAleadamView Answer on Stackoverflow
Solution 4 - JavaNickTView Answer on Stackoverflow
Solution 5 - JavaHeiko RuppView Answer on Stackoverflow
Solution 6 - JavayouriView Answer on Stackoverflow
Solution 7 - JavaernellView Answer on Stackoverflow
Solution 8 - JavaStanView Answer on Stackoverflow
Solution 9 - JavaPēteris CauneView Answer on Stackoverflow
Solution 10 - JavaNareshView Answer on Stackoverflow
Solution 11 - JavaNareshView Answer on Stackoverflow
Solution 12 - JavaFrVaBeView Answer on Stackoverflow
Solution 13 - JavaluvieereView Answer on Stackoverflow
Solution 14 - JavaEwoksView Answer on Stackoverflow