Whether your native Android app is a pet project or has millions of users, you probably need the right tools during development to help you modify persisted data in real time, simulate a slow/unstable HTTP(s) connection, detect bugs as fast as possible, or create mock servers to anticipate the development of a feature. We’ll make a demonstration of all the tools we use in 2016 to write maintainable code and improve our productivity.
My name is Gautier. I’m very happy to be at Mobilization in order to talk about the 2016 Android Developer Toolbox.
It was the first day of my new job at a new company. I’m being paid to live in a warfield that was a legacy project which I have to maintain. I like the warfield and the project but I realized that I was not prepared for it at all. I had some tools like a good helmet and a small knife. They were okay but were not suitable for the job. I had to use the right tools for the right job in order for me to gain productivity and also improve the overall quality of my work. So I chose the right tools and I’m doing much better work now.
Choosing the right tools for your Android Development (0:34)
This talk is about choosing the right tools for your Android Development.
The first tool is Gradle. Almost everyone uses this already unless you’re into Maven or Kobalt or Buck. A great thing about Gradle Android Plugins is that you can create build variants.
Build Variants (1:53)
Build variants allow you to create different versions of the same application, with almost the same source code and with slight changes. For example, you can create two applications — one is a free model and one is paid. They have the same source code, but with two types of build variants.
A suggestion for your workflow is to have two build variants, one for internal and one for production. Internal will be for your company (for people inside your own company) and production will be for the play store (for your customers). The purpose for the internal build variant is for you to embed a lot of tools that will help you debug and locate issues easily.
Inspiration: U+2020 (3:03)
My talk will focus on tools that you can embed in your internal version. I found this idea in the U+2020 sample application which is a gold mine for every Android Developer. It’s a demonstration of a clean and advanced integration of Gradle, Dagger and many other libraries.
Debug Screen (3:30)
Here are examples of what you can do to the internal version:
If you have a menu drawer on your app, you can add a new entry called Debugger. In this entry, you can add a lot of stuff to help you develop or assist you during development. Examples are simulating a notification, showing any notification, displaying a different activity, and more. If you don’t have a menu drawer entry, you can create many different statable activities in your Android manifest. The manifest merger will take care of merging the two statable activities when it builds the app. As a result, you have one application with two statable activities. One shows the normal activity of the your application and the other one shows the internal activity. The internal activity is a settings activity where you can display some builder device information, change endpoint, show some logs and more.
Mobilization 2016 Application (4:46)
I took some inspiration from U+2020 and I created my own app to manage my procedure during Mobilization. I can select some of the talks and it will notify me when the talk is going to start. I can see information about the talk such as pictures, speakers, location of the venue, everything. You can fork this project later or clone it. All the tools that I’m going to talk about are embedded in this project. Feel free to clone and steal the source code later.
Measuring Tools (5:15)
Let’s start with measuring tools.
Android Studio (5:20)
In Android Studio, when you click on the Android Monitor Tab at the bottom of the screen, it gives you the possibility to measure the memory, CPU network and CPU usage.
Measuring Memory, CPU Network and CPU usage (5:24)
In my video example, the left is a blue curve which is a memory footprint of the application. Currently, it’s taking around 16 MB. There are some yellow spikes which means data is being loaded (pictures/images) through the network. A lot of spikes mean I have a lot of network calls but if I scroll again, you will see I don’t have any more spikes. So Android Studio tells me directly that I’ve implemented an image cache and my image cache is working properly. Because every time I scroll, I don’t have spikes anymore. The memory curve is in blue. And it has some drops which may mean that I don’t have memory leak issues because it tells me that the system is freeing some memory which is a good thing.
Detect Memory Leaks (6:36)
But what if I had some memory leak issues? I can see that my application is taking around 136 MB of memory which is way too much. I can click on the “Dump Java Heap” button and it will generate an hprof file. I will click on the Analyser tasks to make sure to detect leaked activities. I will run an analysis on Android Studio and it can tell in a few seconds which activities in my application are leaking.
Get more development news like this
I can see that I have a lot of memory activities that are leaking. What I’ll do is select the first entry every time. Android Studio tells me directly the source of my leak. Because I was using an analytics framework that keeps references of context, it will never give a private field, it will never give up references. Finally, the analytic framework I’ve implemented is keeping references of my context and these are never destroyed.
Leak Canary (7:48)
If you don’t want to depend on an IDE to detect leaks, you can embed Leak Canary in your application. Example scenario is if you have an open source project and every time you receive a pull request, you want an instrumentation test to start and detect memory.
Frame Rate (8:10)
To measure frame rate, you can integrate the Takt library. It’s one line of code added to your ‘build.gradle’ file and one line of code in your main application. Once you integrate those two lines, you can directly see the frames per second.
In the video demo, you can see my application running about 60 fps. But when I open this picture of David Freemont, I can see the frames drop from 60 to 40 usually. So as a reminder, if you want your application to run smoothly in 60 frames per second, you should make sure the code in the UI thread does not take longer than 60 milliseconds.
To get the duration of the method (for example, if it is always less than 60 milliseconds), you can embed a gradle plugin called Hugo. You only need to prefix your classes or methods with ‘@debugLog’ annotation and then you will see the duration in your logs. For example, in the video demo, the init graph method is called and it took 30 milliseconds. The ‘onCreate’ method took 73 milliseconds which is way too much.
You can also do this manually using ‘system.nanotime’. Do ‘system.nanotime’ when you start your method and when you end the method and do a diff.
To color search your application logs, I strongly recommend you to use Pidcat, a color command line logcat that helps you filter by package name or option tag.
Here in the demo, I write
pidcat mobilization. I can see the logs of my application coloured and filtered. It is very easy to install. For Mac,
brew install pidcat. For Linux and other package manager, you can just apt-get install pidcat for example. Personally, when I’m developing apps, I always have my terminal open running with Pidcat in order for me to see my logs easily.
Android DevMetrics (10:38)
If you are using Dagger, you may notice that sometimes initialization takes some time to complete to provide object to the dependency graph. To know the duration, you can use Android DevMetrics — only one line in your build.gradle file and one line in your application.
In the demo, Picasso took 14 milliseconds to provide it in my graph. Others like Retrofit took 47 milliseconds.
Code Static Analysis Tools (11:10)
Now, let’s focus on tools for good quality, starting with code static analytics tools. If you came from last century, you may already know PMD, Checkstyle, FindBugs. Now cool guys are using Lint, Error Prone, or Infer.
You should use Lint to help you locate issues. For example, you wrote some method call that cannot run on lower API. Your application will crash and Lint for Android will warn you about it. Every time you write a code that has any issues, your IDE will tell you directly. Code static analysis tools will assist you during the development.
Sonar Lint (12:00)
Another recommendation is SonarLint. SonarLint is a plugin for Android Studio similar to Android Lint but focused more on Java. It will inspect every line of your code and will warn you if there is anything wrong.
Demo Code for Sonar Lint Example (12:20)
In the demo code, there are a lot of things wrong in my code. Here, I’ve used import field that is generating some code. I wrote some public field inside a private final. My modifiers are not written in the right order. I have some useless parentheses. My code can compile and work but people reading this code will spend more time reading this code. Sometimes I may write something that is wrong. Sonar’s plugin is very good because it suggests to you if something is wrong–for example: remove this unused private field. Lint and SonarLint are like good friends that gives you advice if something is wrong. You should not trust code static analysis tools 100% because it may also give you some false positive warnings.
If you want more metrics, you can install SonarQube. SonarQube is a web application; not a plugin for your IDE so installation is via Dockerfile or on Docuweb.
SonarQube Dockerfile Example (14:09)
Create a Dockerfile, launch it and it will create a web server. Once your SonarQube server is started, you just have to write some lines of code in your ‘build.gradle’ file and add some configuration.
It’s best to use Docker for SonarQube because I don’t want to impact the configuration of my machine.
Examples regarding impact on machine configurations and benefits of using Docker:
If I have two machines, one for my professional machine and one for my own computer, in my own computer, I don’t want to install a lot of stuff like these tools. But sometimes I would need to use my own computer for professional purposes (development), hence the need for me to install these tools. Instead of installing it, I can just run my Docker container and I will have all these stuff available for me on my own computer. Another example is if you’re building Android from the sources. Installing Android in your machine is pretty complicated for the first time. You have to install a lot of dependencies and sometimes you don’t want that in your personal machine. A solution is to create a Docker container that will contain all the dependencies to build Android from the sources without impacting the configuration of your initial machine.
Sample Code for SonarQube (15:29)
In the example code, the first block is the name of my project, Mobilization. Second block is where the SonarQube server is located. Third block is some information where my test reports.
FROM java:8 MAINTAINER Nilhcem RUN DEBIAN_FRONTEND=noninteractive apt update RUN DEBIAN_FRONTEND=noninteractive apt install -y wget unzip RUN wget -q https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-6.1.zip RUN unzip -qq sonarqube-6.1.zip -d /opt/ RUN rm sonarqube-6.1.zip EXPOSE 9000 CMD ["/opt/sonarqube-6.1/bin/linux-x86-64/sonar.sh", "console"]
SonarQube Sample Output (15:52)
If I want SonarQube to give me information about code coverage and everything, just start analysis. By running the SonarQube server, it will tell you an overview of the complexity of your application. Here my application has three bugs, like 16 days of technical debt. That means to make my application perfect in terms of usability, readability, and maintainability, I should spend 16 days. Instead of bringing more features to my application, I’ll fix the existing issues first–issues that are detected by SonarLint. SonarLint shows what is wrong and it could take me 10 minutes to fix.
Testing Tools (17:16)
Most of our apps communicate with a server. It’s a bit tricky to test these apps. A good test is like given, when, and then; and then is always compared to the given.
Mock Server (18:18)
One tool you can use is creating a mock server. A mock server is a server that will always return the same data. You can create a mock server in different ways. I prefer NodeJS and Express because I can create one with only a few lines of code. Note: This is not for production but for development testing purposes.
Sample of NodeJS + Express Server (18:42)
Like here, I have 15 lines of code. First block is about initializing the server. Second block is getting the content of the data via JSON file using HTTP get
Sample simulating a slow network call (19:35)
Example: If you want to simulate a slow network call, you can create a loop that will do nothing for a long time. Netflix has something called Chaos Monkey. It’s an application that destroys the server every time. Some suggestions: You can sometimes destroy queries for your own purpose. Then test that and return errors as needed.
Using Mock Server in the Mobilization Application (20:40)
When I was creating the Mobilization application, I didn’t have any data yet such as the schedule. So I created a fake mock server with some cats. Since I have some mock data already, I can easily start my development. I don’t need to create my development at the last moment. Make sure that testing and production server should be different. We can easily do that in the gradle configuration by creating a variable that tells you the location of your server and then modify it as needed.
Host Editor (21:50)
If you don’t want to modify your source code, you can use the Hosts Editor which basically creates an entry to the
/etc/hosts file then associate the necessary IP to the host name variable.
HTTP Debugging (22:34)
Next must have tool is HTTP Debugging Proxy Software called mitmproxy, a command line tool written for GNU/Linux Library. You can use Fiddler for Mac (this is free) or use Charles proxy (paid software). Personally, I use Charles Proxy on my Linux and Mac. When creating an application that relies on network, you often have these following needs:
- You want to simulate a slow network connection,
- You want to repeat some queries,
- You want to check responses, or
- You want to add breakpoints to network code to consolidate code, edit a request or response.
These tools such as Fiddler or Charles Proxy will help you with that.
Charles Proxy (23:07)
In the video demo, I have modified a server and created a breakpoint. I clicked on the tortoise to simulate a slow network call, then I will execute my query. I will now edit my response to “Hello World by Keynote Larry Page”. Once the Mobilization app loads, it should show a keynote by Larry Page”. So why is this important? Sometimes the backend team may request if a field they created before in their JSON response can be removed or set to null. They want to make sure that the application you are making won’t crash. We can simulate their request using the HTTP Debugging Proxy Software and then see if our app will crash or not.
Android State Restoring (Testing app state restoring) (24:53)
Android system can destroy your application at any time if it’s not visible. Developers sometimes fail to test this behavior properly.
Don’t Keep Activities (25:06)
One way to do this is to use Don’t keep activities in the developer options every time you go to the home screen. This will lessen the activities but it is not enough. It does not keep activities but it keeps the references of your application object.
Let say you have a splash screen. Splash screens are not a good practice in Android Development but sometimes you may need it in your application. What’s happening in your splash screen is it’s loading data from the network then saves the data either in a single tunnel as an application object or a single tunnel in your dependency inject or your own single tunnel. Even if you enable “Don’t keep activities”, you will still see that the application is still working fine because the single tunnel was not destroyed.
Fill Ram (26:07)
To test this properly, you can use Fill RAM. It’s a tool that creates or forks a lot of processes until your phone has no memory. Then the Android system will kill every reference of activities. It works fine if the system restores the state of the activity. This tool is useful for QA.
Android Device Monitor + Stop Process (26:58)
The faster way is to use Android Device Monitor. Start your activities, go to your home screen, kill your processes and wait for Android to recreate everything again. After killing the application in the Android Device Monitor and restarting your app by tapping on your app icon, you will initially see a white screen. Android is recreating the activities that is why it is shown as a white screen. You can test this behaviour using the Android Device Monitor.
Analyzing Tools (27:49)
Developer Options (27:54)
There are a lot of useful tools in the Developer options:
Show Layout Bounds (27:58)
Show Layout Bounds shows margins and bounds of your layout in order for you to make sure it is in the right order.
Debug GPU Overdraw (28:07)
Debug GPU Overdraw can help determine which part of your app has more overdraw. An app may draw the same pixel more than once within a single frame in an event called overdraw. If you have turned ON the Debug GPU Overdraw in the Developer Option section, your screen will show different colors. These colors have different meanings–like RED means that the pixel was overdrawn 4 times or more.
And, you can use the Developer Options to optimize your layouts like check if you have too many nested layouts.
Another tool I like to use to analyze layout is the ** ‘UIAutomatorViewer’ **. This is included in the Android SDK.
- Connect your phone via USB
- Click on the UIAutomatorViewer button (this will take a snapshot of your application)
- Browse the view hierarchy of your app and modify it according to your needs. Example: you can easily modify the Speaker’s Name (label) to bold.
In the demo, I click on this area and it can show me directly the ID of my view. I grab it in my code and I can directly see where my view was created and which time. You can easily inspect any app that is not yours. For example, while using Twitter, you can see how flat Twitter’s view hierarchy is, respecting accessibility. ‘UIAutomatorViewer’ is the good tool to inspect different layouts of any app.
Animations Testing (29:45)
Regarding animation, there are times when I have glitches in my animations and I cannot see what it wrong with them. To debug this, we can increase the animation scale in the developer option to slow down your animation.
Animations Testing (another style) (30:03)
Another style is creating a screencast of my animation. Then I can
adb shell screencast then open it using VLC. Every time, I press E, I can see it frame by frame.
Compiling Tool (30:38)
Next is the compiling tool.
When you give your customer your application either as an App on Google Play Store or APK, they have the ability to access your source code even if it uses ProGuarded. When I was a consultant, I had a customer who had inserted their FTP location, FTP URL, FTP password in their source code. It was insane because it means anyone can connect to their FTP and modify their code. So don’t forget that in everything you ship, its source code is open for everyone to read.
If you want to see what people can see in your application you can use APKTOOL, DEX2JAR and Java decompiler. APKTOOL is a decompiler tool that decompiles your APK into a DEX file that you can convert into a JAR and then use Java decompiler to see the source code of your application.
Another easier solution is JADX. JADX is a graphical user interface tool that can visualize everything inside your application. People can read you source code in only one minute, so make sure it’s good.
And inside Android Studio, you can build Analyze APK and be able to directly visualize the content of your APK inside Android Studio. You don’t need an external tool.
Stetho by Facebook is a tool that helps you inspect your application while you interact with it. Results are shown at real time via the Chrome browser.
Stetho + UI (32:36)
For example, If I want to see the view hierarchy of my app, I’ll just connect my phone via USB to my computer, open Google Chrome and see the content of my view hierarchy directly.
Stetho + Network (33:20)
With Stetho, you can also analyze your network code.
In this video demo, I have the network tab, I start my application and I can see the HTTP codes I did–the HTTP editor and the inset. If I load some speakers’ images, I would see the images.
A better feature is the resources tab. You can modify in real time the data being passed in your application. It can modify any database such as SQLite database or Realm.
Stetho DumpApp (35:22)
An even better feature with Stetho is DumpApp — because we, Android Developers, do not depend on web browsers to debug applications. DumpApp is the same except that it is using the terminal. So with DumpApp, we can interact with your application via the terminal or shell and not the web browser.
Stetho + Custom Plugins (40:10)
You can easily create your own DumpApp Plugins.
Choose yours according to your needs and tastes. Explore them and create your own toolbox. If you can’t find the tools that you need, make your own and share them to the community.
Lastly, the best title for my talk should be Example of Developer’s Toolbox instead of the 2016 Android Toolbox.
About the content
This talk was delivered live in October 2016 at Mobilization. The video was transcribed by Realm and is published here with the permission of the conference organizers.