When testing Android applications (or any mobile device applications for that matter) nothing beats running it on an actual, physical device whilst connected to your favorite IDE, I think most developers would agree with this. Physical devices, however, cost money and for a hobby developer the price can sometimes become an insurmountable obstacle.
Having finally released my first Android app into the wild it only took someone a few minutes to find the first bug that only exist on certain devices, this tip outlines the steps I took to find and fix it without having to buy a new device.
The bug I had in my application was causing the screen to go completely black for a brief, 2 seconds, period, it wasn't happening on any of the four different devices I have available for testing and I had never seen it using the emulator either.
The actual code that caused the bug was this line;
(int)(Math.min(1.0f, alpha) * 255.0f),
I used it to gradually fade in some elements and on devices running Android version 4.1+ the screen would be blank regardless of the value of alpha (which changes from 0.0f to 1.0f). No exception was thrown so I couldn't even look at a crash report.
These were the steps I took;
1. Reproduce it
This failed completely, I tried all my available devices plus running the emulator in several different modes. The problem with the emulator is that to emulate the later Android devices that usually have quite fast processors my crappy laptop struggled to keep up and when setting the specs to match the device the bug was found on caused the emulator to run out of memory.
2. Read the code
I like to think my project is fairly well written so my initial solution was simply to read the code and try to figure out what was happening and why it was happening. The only problem with this approach is that anything concluded is never more than a guess and without a way to reproduce and verify the bug it's impossible to prove that it's been fixed
After reviewing my code I decided that the problem must be
canvas.saveLayerAlpha throwing an exception, and the reason the application isn't crashing was that I have (incorrectly) coded my rendering loop very defensively.
3. Buy a new test device
My wife explained to me in no uncertain terms that me buying a fifth device was not going to happen, so this step was never implemented
4. Samsung RTL (remote test lab)
This step is the cool step, this step is my tip!
Having failed to prove and resolve debug using my normal plan of attack I stumbled across Samsung Remote Test Lab, this is a series of devices that you can get remote access to using a Java Web Start application.
You can find the test lab here; http://developer.samsung.com/remotetestlab/
To get access you'll need a developer account, which is free, and some credits, which are also free. Fifteen minutes of time on a device costs 1 credit and you get 20 credits per day to use.
The site allows you to pick a device and sometimes a specific version of Android and then reserve that for a fixed period of time.
This is absolutely awesome I think and would have saved me so much time during development had I known it existed. Free access to a range of devices and OS versions just a click away!
And no, it's not perfect, far from it, but access to a range of test environments that would have cost me thousands of pounds to acquire (if I was going for actual devices) can only be a good thing.
Using a Galaxy SIII device running Android 4.1.1 I was able to;
- Download my application from Google Play
- Prove the bug
- Build a fix locally on my computer
- Upload that directly to the device (no need to wait for the slow Google Play publishing process).
- Verify my fix
It took me a while to figure out how to work the device, things like right-clicking outside of the screen to get a context menu to control file upload and LogCat wasn't intuitive I think, nor was realizing that unless a process called RTL Agent is running on the device it's not going to be much use at all.
All the minor annoyances aside; this is a really powerful tool for a hobby Android developer, so my Tip is make use of it.