Sunday, April 28, 2013

How to avoid unstable releases - StrictMode

The following method is less about finding bugs per se, than finding violations of best practices (most importantly: no I/O on the main thread!). It's called StrictMode and has been introduced in Android 2.3 (Gingerbread).

Using it is really simple. Let's say you want to find out if and where you do I/O on the main thread, you'd add the following code in your onCreate:

   StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());

.setPenaltyDeath()
Everytime an I/O operation is executed from the main thread, a stacktrace will pop up in LogCat, telling you exactly where you violated the "policy". By the way, you can filter these messages using "tag:StrictMode".
If the log is not enough for you, you can add additional penalties, like .penaltyDialog (shows a dialog on violations) and .penaltyFlashscreen (only available on newer devices). You can even kill the app: .penaltyDeath (ouch!).

Furthermore, you can set a policy for memory leaks, such as unclosed resources (InputStream, etc):

   StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());

The same tips as above apply for this policy.

For more tips on improving the performance of your app, see the "Best Practices for Performance", especially "Performance Tips" and "Keeping Your App Responsive".

Tuesday, April 23, 2013

How to avoid unstable releases - isUserAMonkey?

*I'm NOT saying that bosses use devices like monkeys or vice versa!
To be honest, this is the least effective way to find bugs. At least if you try to cope with the Activity lifecycle the way you should (read me!). Anyway, it might help find those bugs, your boss would usually find by turning the device a few times, pressing random buttons and... "Force Close". That's what Monkey does.*

You don't have to write any tests for this to work. Instead, you simply install your app as usual (preferably on an emulator) and run the following command from your command line: adb shell monkey -p your.package.name -v 500

I recommend you to tweak this command a little bit, like this: adb shell monkey -p your.package.name --pct-syskeys 0 -p your.package.name.again -v 500

What this does:
  1. --pct-syskeys 0 prohibits keys like Home (which you don't really want to get pressed during a test...)
  2. -p your.package.name.again restricts the Monkey to only interact with Activities in your package
By the way, you can change the number of "events" (keypresses, touch events, etc) the Monkey produces by changing the number at the very end of the command.

You can find more parameters for this command here: http://developer.android.com/tools/help/monkey.html

A Monkey sittin in a cloud

Now you want to automate the whole process, right? Of course you do. apkudo (or APKUDO?) is a service, which has 250 different Android devices, and - more importantly - at least 250 Monkeys which test your app the way we just did locally. The price for testing your app on 250 (read, all?) different Android devices? It's free. Crazy stuff.
You don't even have to sign up - just sign in using your Google account, upload your APK. The Monkeys do the rest for you.

Unfortunately, their user interface is quite unintuitive if you ask me. It took me a while to figure out where I can find the stuff I want to see, but you get used to it...

One more thing: quite a few of the errors reported by APKudo were errors while installing the app (timeouts, container errors, etc). I've already told apkUDO about this, but they haven't replied so far...

How to avoid unstable releases - Introduction

As long as I've been publishing apps for Android, I always managed to break some feature with every update I released. For example, if you happen to use OpenDocument Reader you might have noticed that we release an update on one day (for example, version 2.9) and quickly delivering new updates within the next two or so days (we are at 2.9.2 now). In our case we have two points of failures: Andi, who breaks stuff from time to time by copy and pasting code from one file to another, and me, who 1. mostly simply pulls the changes from Andi and releases an update and 2. breaks stuff by using Andi's code the wrong way.

Anyway, the last few months we kept promising each other not to release yet another update before implementing proper tests... which we didn't, after all (therefore version 2.9 to 2.9.2). But NOW we're totally going to make it! The first step is to implement tests which test only Andi's code. These are not JUnit tests, but we might change that some time in the future.

On my side (Android), we're going to take advantage of everything Android, Google and the ecosystem offers:
  • Monkey
  • StrictMode
  • JUnit tests
  • bug reports (in case everything else fails and a bug sneaks into the app anyway...)

Thursday, April 18, 2013

Extracting URLs from text using Java and Regular Brainexplosions

Human mankind can fly to the moon, jump from the stratosphere down to the earth, but we can't produce a regular expression, which matches all URLs. Oh well...

After searching for a "perfect" regular expression, I came across this site, which shows the result of testing tons of URL-recognizing regular expressions. The result? There's no such thing as a perfect expression, but there are short ones (nearly 30 characters) and ridiculously long ones (1000+ characters!). Of course I want to include a 1000 character long regular expression in my code, right? Escaping it for Java must be a real pleasure...

Eventually, I found one which is only 15 characters: /\bhttps?://\S+/g
Of course, this one hardly matches all URLs, but I think it gets pretty close to a perfect balance between effort and effectiveness.

If you want to know more about regular expressions for URLs, I recommend you to read this article.

Thanks refiddle.com for making testing of regular expressions so much easier. :)

"git status" all the things!

And another script for you kiddies out there!

At work I'm working with quite a few repositories simultaneously, which makes it horribly annoying to check the git status of each project. Of course, I could use something like EGit to see the status directly in Eclipse, but come on...

Here's the script: https://gist.github.com/TomTasche/5414857

It's really simple. In fact, it doesn't even check if it's a directory it tries to cd to. But it does the job pretty good for me. I hope it can help you too!

Wednesday, April 17, 2013

Trim surrounding whitespace from pictures

I was scanning some old pictures lately, and noticed - only after 200 scanned pictures, of course - that they were surrounded by white space, to fill them up to the size of an A4 paper.

Well, there's only one thing one can do in this situation: write a script which trims pictures from surrounding whitespace. You can find the script here: https://gist.github.com/4649500#file-whitespace_trimmer

As this script is written for bash, it only works on Linux systems. I guess there's some nasty way to get bash running on Windows too, but hardly anyone still uses Windows nowadays, right? Moreover, you need ImageMagick installed.

If all of the above applies to you, you can run the script like this:
 whitespace_trimmer DIRECTORY_TO_BE_TRIMMED

In case you're curious what the pictures I needed to be trimmed looked like, here's one of them:
Sample picture to be trimmed