Useful tips to inspect your Android app — Part 1

Georg Modzelewski
Jan 19, 2017 · 8 min read

There are many reasons why the analysis of your Android project is quite a good idea. Besides finding and extinguishing bugs successfully and quickly improving user experience you may also want to speed up your processes to avoid senseless waiting, or become familiar with a new project while doing it.

There are lots of tools to track down memory leaks, one of the most common bugs in Android apps. Other tools help you find code smells. In addition, all kinds of tools exist to analyze the finished Android package files (apks), to collect data concerning the famous 64k method limit or to reduce the general app size.

The intention of this article is to get a feeling for when to use which tool for what kind of job. The two principles here are:

Know your tools

and

Use the right tools for the right job

General

At first some general recommendations to speed up your development processes. If you have recently used a virtual machine and you work on an Intel processor, you should consider activating Hardware Accelerated Execution Manager (HAXM) support, which allows you to run code directly on your host hardware without emulating it. The only drawback here is that your Android VM must be an Intel Atom image which excludes native ARM code.

Download the tool via your Android SDK Manager which will install the package to android-sdk/extras/intel/Hardware_Accelerated_Execution_Manager. Make sure the virtualization support is activated in your BIOS settings before installing HAXM. If your VM starts with HAXM your console output should show some output which mentions HAX.

HAXM enabled VM starting console output text

The performance improvement between ARM and Intel Atom Builds is about 90 %, activating HAXM will get you another 30%.

First boot time (tested on a MacBook Pro i5, late 2013)

If you want to work on your desktop but use your physical device instead of a VM, it is annoying to constantly change input devices and it slows down your development process significantly. Instead, a convenient solution would be to simply mirror the screen of your physical device to your desktop.

Prior to Android 5.0 the only way to receive at least screenshots was to use the command line command adb screencap -p, which is very slow. Since Android 5.0 it has been possible to get direct access to the graphic buffer, at least if you have root permissions. However, this feature was blocked in Android 7.

Plenty of tools will help you with presenting apps from your physical device by mirroring your device screen into a window on your desktop. One of them is Vysor. It’s free, but ads are shown every now and then.

Vysor showing the mobilcom-debitel cloud app

It is a Google Chrome extension and can be installed via the Chrome Web Store. Once installed, any Android device you connect to your computer gets the app installed automatically. Afterwards the connected device’s screen will be shown in a Vysor window.


For improved logging you can use a small command line tool named PID Cat, which is basically a color coded logcat. It is a python script, which you can install on macOS via homebrew (brew install pidcat), or manually set a path variable to the script. You only need to call pidcatwith your specific app package name to start.

PID Cat

One tool I frequently use is the Android Studio Plugin ADB Idea.

It is a simple small pop-up which opens up when you type Ctrl+Shift+A (or Ctrl+Alt+Shift+A for Windows) to execute adb operations quickly. You can install it using the Android Studio plugin repository.

As you can see, the app is simple, but it has all the adb commands you need. In the latest version it also supports restarting the app with an attached debugger.

ADB Idea

If you want to change certain app settings at runtime and start custom events you can use a very small nice tool named Bee. The tool can be accessed via a floating button added to any Activity defined by the developer. By clicking on the bee button certain debug events can be fired, e.g. displaying a notification or changing some preference values. For installation you will need to add the dependency and call the Bee object with an activity context.

Bee

QA and software testing often involves testing REST API routes. One way to test how your app reacts to specific responses is to use a mock server. Node.js and the express framework are a very easy way to create a simple working API in no time. Here is an example for a simple API which returns a JSON file at a GET request:

var fs = require(“fs”);
var express = require(“express”);
var app = express();
var port = app.get(“port”);
// Competition list
app.get(‘/competitions’, function(req, res) {
res.type(‘application/json; charset-utf8’);
res.status(200).send(fs.readFileSync(‘data/competitions.json’, ‘utf8’));
});
// Starting the server
app.listen(port, function() {
console.log(‘Express server listening on port ‘ + port);
});

If you like to go deeper into mock servers using express, have a look at node.js express dev guides.


Another tip for testing purposes is the use of the Fill RAM app, a small Android app to test your app against low memory and state issues that are common reasons for crashes. You simply open the app and start the ram filling task.

Fill RAM app

Last but not least, the often forgotten Android Studio Monitor provides useful information about the current memory status. Big humps in your memory usage can indicate memory leaks, significant deviations in your network usage may be pointers to caching problems.

Android Studio Monitor

This tool comes with Android Studio, just open the Android Monitor window at the bottom of your Android Studio IDE.


We have seen many general tools and recommendations for app development and analysis. In the next sections, we will discuss this in more detail.

How to track down memory leaks easily

Let us start with a nice small example of how to create a memory leak. Consider an activity which holds three fragments in a ViewPager (e. g. via a FragmentPagerAdapter). The ViewPager holds the two adjoining fragments in the cache, so all three fragments get loaded.

The top fragment here has a callback which needs the activity context for resource handling. Now let’s change the view to the bottom fragment.

The top fragment is no longer needed in the cache and the garbage collector should collect and clean the unneeded references.

The callback still holds the static reference to the activity context. And this creates the memory leak, the garbage collector can not clean up the top fragment and all of its resources, because it is still needed in the callback.

This memory leak can easily be solved via WeakReferences. For further reading regarding that topic please check this article from my co-worker Johan Olsson.


There are two easy ways to detect memory leaks. The first is to analyze the Java heap via Android Studio. If you remember the view of the Android Studio Memory Monitor, you can see five small buttons located below the “Monitors”-tab.

If you click on the “dump java heap”-button you will see that this button appears in the monitor progress view:

After a short loading time a window appears. On the right side there is the tab named “Analyzer Tasks”, open it and perform the analysis via click on the play button.

If in the section “Analysis Results”, you see the bulletpoint “Leaked Activities” then — congratulations — you have found a memory leak.

Found memory leak via java heap dump

There are other ways to detect memory leaks in your app, as well. One of them is a tool called LeakCanary, an Android library. To get started you add the dependencies into your debug builds and call the LeakCanary install factory method within your app context. If a memory leak is detected the user gets a notification. For more information please check the FAQ.

LeakCanary

These are just a few ways to detect possible memory leaks. However, you should not completely rely on the tools since not every memory leak may be detected. The best way to avoid memory leaks is to be aware of the consequences your code has. This can be achieved by studying how the overall memory architecture works in a computer and how Java incorporates it. After a while you should get a feeling for it.

This article shows many tips to improve your Android app, your workflow and how to detect memory leaks. In the second part of this article, I will introduce you to more analysis tools, technical debt identification und in-depth APK checking.

We have seen many tips to improve your Android app, your workflow and how to detect memory leaks. In the next part of this article we will get information concerning all kind of measurement tools, technical debt identification and APK analysis.


Don’t miss the next part and follow freenet Engineering for further Android App Development tips.

Update: You can find Part 2 here.


Interested in how we develop software? Join our team in Hamburg, Germany!

freenet Engineering

Software Engineers at freenet build a variety of web, mobile, desktop and backend applications. This is our engineering blog.

Thanks to Kay Butter, Timo Arfert, Johan Olsson, Sascha Üreten, and Lutz Harder

Georg Modzelewski

Written by

Developer

freenet Engineering

Software Engineers at freenet build a variety of web, mobile, desktop and backend applications. This is our engineering blog.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade