For those of you who have been following the latest developments in the Android world you might know that Square Inc. launched some open source projects the week before Google I/O 2013. Since they rely heavily on open source software, it was a way to give back to the community.
Today I’ll write about one of those Android libraries, Picasso, that I’m actually using to develop the new version of our Android app and that really made my life easier as a developer.
If you have ever tried to develop an Android app or would like to know how to write one, it will probably have images and most certainly, images downloaded from the Internet.
Dealing with images in Android is extremely hard for a beginner and specially frustrating if you don’t have enough background in computer science. Fortunately now, the official Android Developers website has a lot of documentation on this subject accompanied by sample projects that you can use to make your life easier.
If you’re a full-time Android developer I’m sure you’ve developed your own version of your AwesomeAsyncImageView.java. Everyone did!
Since I want this article to be understood my most people that use Android and are interested by some more technical details, here are some problems that happen when you’re dealing with images.
First, you should have in mind that your device’s battery is what feeds the CPU and the more you use it, the less battery you’ll have. I’m sure that’s pretty obvious for everyone.
So, let’s say you want to display a list of news articles, maybe just the title and a preview image just like we have on our home page.
The ANR problem
First, you’ll have to contact the server to ask for some news articles (the format in which the server replies to you in irrelevant now). It can give you a title and a URL for the image for example and then you start downloading the images one after the other and suddenly your applications hangs with the terrible ANR dialog (Application Not Responding).
Why? Because, since your app is busy downloading the images, it doesn’t have time to draw itself on the screen and the Android OS thinks that your application is hanged. Of course you, as a user, can always press “Wait” and let the app finish it’s work, but it’s a very bad user experience (UX).
Improving the UX of our app will force us to learn the concept of threads. Threads are just concurrent units of execution, which means that they run at the same time and every app has at least one main thread, usually called the UI thread for User Interface. This thread is responsible to draw the app on the screen.
This problem is solved very easily by creating a new thread that will download the images in the background and when it’s finished it tells the UI thread, “Hey! I’ve just finished downloading an image, you should display it.” This way you never get an ANR dialog.
First problem solved, but there are more!
The screen rotation problem
Let’s say you rotate your screen, the app will have to redraw itself because maybe you have a landscape optimized layout and sadly you’ll have to download all the images again. Waste of battery power but you can also have a limited data plan and it will eat some more kilobytes of your monthly traffic.
The memory caching solution
So now you’ll have to be familiar with the concept of cache. Which is a component of your app that will store data so that future request will be served faster.
A cache will make your app use more memory of course, but memory is cheap and the benefits are much greater than the memory usage.
With a cache, your app behaves like this, the UI thread says to the cache “Hey! I need image nexus4.png”. The cache doesn’t have anything (called a cache miss) and downloads the image, gives it to the UI thread, but keeps it in memory. You rotate the screen, the UI thread asks for the image again, the cache says “Good! I have it here! Take it.” (called a cache hit) and it didn’t have to download the image again. We’re in 2013, we just don’t care about those extra kilobytes of memory if it speeds up the app so much and saves us battery.
The 'quit app' problem
One final problem, let’s say you press the Back button, the Android OS kills the app and you open it again. Sadly, you’ll have to download everything again. Fortuntaley there is also a solution which will make the app use even more memory (disk space in this case) but no one cares because disk space is cheap. Instead of using just memory cache, you can also cache on disk. Your app will behave as above but this time, after giving the image to the UI thread it will store it in disk, just in case the app dies and it needs the image again. This time, the UI thread asks for the image, the cache doesn’t have it in memory because the app was killed, it checks the disk, it’s there, loads it into memory, keeps it there and returns the image to the UI thread and we didn’t have to download the image again.
To wrap up, what makes this Picasso library so awesome is that with a single line of code it takes care of all this stuff for you, so you, as the developer, will have more time for more interesting things than managing images.
I hope that you learned a little bit more about the behaviour of Android apps and this very common computer science topics.
Source: Square Inc.