
Month: June 2010
Android Words of Wisdom? Catch Everything
Every mobile platform has its pitfalls that separate the great apps from the “oh my god, they released THAT!” apps.
Most of these landmines revolve around a couple of vital issues:
1) Gracefully failing when something “bad” happens (network connection drops, memory is in scarce supply, battery is dying, something is null that’s not supposed to be null, etc.), and
2) Knowing that you NEED to gracefully fail before the Operating System heaps a big helping of fail on you, pre-emptively, for kicks and giggles.
By gracefully failing, I mean doing something to mitigate any negative effects to a user (closing open files if the app needs to shut down, alerting the user to a problem without simply crapping out) in an orderly way, and NOT simply having your app exit.
And by “knowing” that you need to take some action on behalf of your application, I simply mean that you need to put in as much error handling – everywhere – in your applications as you can possibly stomach.
In the case of Android applications, this means that wherever possible, you need to be using try / catch in code that has any chance of failing on IO errors, communications, or low memory.
For most libraries that throw exceptions, developer environments like Eclipse will tell you that you need to wrap certain calls in try / catch or the app won’t compile. BUT – and this is a BIG BUT – try / catch won’t catch everything, unless you tell it what to catch.
Where this usually winds up biting you in the ass, especially with Android and its 16MB VM limit, is reading large photos from the camera’s gallery. While Eclipse will “let” you compile code to read bitmaps from disk with just a catch for IOExceptions, it will not require that you put in a catch for OutOfMemoryError – which is by far the error you’ll encounter the most when working with large numbers of bitmaps within an Android app.
So… what’s a careful developer to do?
At a minimum, this:
1) Catch every possible error / exception within as many blocks of code as you can. I don’t always live by this dictum, much to my eventual chagrin – but I do try (no pun intended).
2) Never read a bitmap from your Android device without “downsampling” it first. You’ll almost always run out of memory, especially with the newer 8 megapixel devices. The following method will read a bitmap from a device and sample it down about as safely as one can on Android:
public Bitmap readBitmap(Uri selectedImage) {
Bitmap bm = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
AssetFileDescriptor fileDescriptor =null;
try {
fileDescriptor = this.getContentResolver().openAssetFileDescriptor(selectedImage,"r");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
finally{
try {
bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
fileDescriptor.close();
}
catch (OutOfMemoryError e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return bm;
}
This is about as much as we can do to mitigate “bad things” happening when reading bitmaps into our apps, but we can also do one more thing to help, and that is
3) Release any bitmap memory as soon as we are through using it. I usually use a method like the following:
// Clear bitmap
public static void clearBitmap(Bitmap bm) {
bm.recycle();
// revised 08/15/2010. As a commenter astutely pointed out, bm is not a passed reference.
// To free the memory associated with this bitmap (as intended),
// bm should be set to null in the caller.
// bm = null;
System.gc();
}
Recycle frees up the memory associated with this bitmap’s pixels, and marks the bitmap as “dead”, meaning it will throw an exception if getPixels() or setPixels() is called, and will draw nothing.
Assigning null to the bitmap will free its memory.
And calling System.gc() indicates to the virtual machine containing your app that it would be a good time to run the garbage collector.
Solid error handling and graceful program exits are often times more art than science. But like anything else in this life, one can never have too much of a good thing.
Try {&&} catch (everything) {YouCan();}
Happy Father’s Day
I spent a wonderful weekend with my two sons and my wife, Melissa, on the Gulf Coast of Florida, capped off with seeing Toy Story at Downtown Disney on the way back home… and found yet another great movie memory that will always remind me of how much I love my family and my two boys.
The Toy Story Franchise is arguably the only film series – aside from The Lord of the Rings – where each successive film outshines the previous one.
Toy Story 3 is a surprising gut shot – and I mean this in the best possible way – for any parent.
You’d have to have a 50 cent block of ice in the place of a heart not to feel something at the end of the movie. I won’t spoil it for anyone, but the last 20 minutes are even better than the prologue segment of “Up”, which I considered up to now to be the best of anything that has come out of Pixar.
Pixar movies have always held a special place for me.
“Up” hit home for me, personally, in a way that most “grown up” movies never have. My wife still hasn’t seen it, and is a little reluctant to, because it reflects so much of what we went through in our journey to become parents.
My oldest son and I watched “Nemo” about a dozen times while we passed time waiting for potential buyers to view our house back in 2003. I can’t hear “There, there, Daddy’s got you” without tearing up a bit.
And even though I got off to a somewhat belated start as a parent – at a time when several of my friends are welcoming their grandkids – I still have trouble remembering what life was like before my sons arrived.
I’m having even more trouble imagining life without them in the all too fast approaching future, when they strike out on their own.
Seeing Toy Story 3 reminded me all too clearly about how quickly our lives together pass (even more so than my 30th high school reunion I missed this weekend.)
I wish every dad a Happy Father’s Day. I hope you were able to make some great memories today.
I know I did.
Android Bordered Bitmaps
From time to time, I find myself wanting to do something in Android… and finding that I can’t get there from where I currently happen to find myself.
Today that something was “draw a border around an bitmap.”
My eventual solution was to do the following:
- Create an ImageView and wrap it inside a LinearLayout.
- Create a solid bitmap of the color that I want the border to be (using Paint and Canvas) and set it as the background for the LinearLayout, making sure that the size of this bitmap was 2 pixels longer and wider than the bitmap that I wished to border upon.
- Put the bitmap that I want to display in the ImageView, and make sure I have the gravity of both the ImageView and LinearLayout set to “center_horizontal | center_vertical“.
The solution, while not as simple as say setting an attribute named “border“, is workable enough.
I’ll include sample code over the weekend.
For now, it’s late Friday evening and time to do something relaxing.