Starting With Android - Managing Images
I’ve started with Android development a few months ago with the upcoming We Heart It app. Here are some random thought and impressions I had during this period, and the motivation behind building the Android-ImageManager library:
API Complexity: Compared to the iOS SDK, at first, the Android SDK seemed to me overly complicated and over-engineered. There are specific patterns you need to follow for most common scenarios and avoiding them just end up making it harder, so you basically have no choice. For example, the AccountManager API, which you need to use if you want to create an Android built in user account. There are several interfaces you have to implement, services to create, methods to override, etc. It is very painful overall.
Version Compatibility: If you want to support a decent range of devices and Android versions, you’ll spend countless hours of testing and have to buy 10 different phones and tablets, since the Emulator is simply unusable (terribly slow). Stick with already proven open source libraries for a less painful development experience, like ActionbarSherlock, ViewPagerIndicator, HoloEverywhere, DiskLruCache, etc. You can thank Jake Wharton for most of that awesome work.
Automated Testing: Painful as well. We decided to go with Robolectric which basically stubs all the Android APIs for you. That has pros and cons, but definitely good that your tests run super fast (like seconds) and you dont have to keep stubbing everything in order to make your tests work. All you need is a simple jUnit project. Haven’t looked much into Integrated UI tests yet, but we definitely want to check that out soon. Android provides some classes for this job.
Memory Management: This would deserve an entire article just for it. If you start working with images, galleries etc. or just do something that is not plain trivial, you’ll sooner or later start seeing
OutOfMemoryError. It is hard to get it right, and there are many things you need to be aware of when building an application, specially for We Heart It, which is totally image-heavy. Some of the techniques definitely include
- Cache your images so you don’t keep requesting the same images over and over again and wasting all the user’s data bandwidth;
- Request a sampled version of the images that is adequate for the screen size/display dimensions where it is gonna be used;
- Recycle your bitmap when it is not being used anymore, so you can reclaim unused memory faster.
- Avoid creating too many instances: When working with a REST API, it is easy to instantiate new objects all the time and keep them around, send to the Activities, etc. Try to keep your footprint to a minimum. Think about all object instantiation and whether it is needed or not. Sometimes all you need is a simpler version of your domain object to be shown in the UI, so keep a simpler version of your model that contains only the needed information to be displayed.
Some of these reasons above motivated me to create the library Android-ImageManager, which takes care of caching and storing the displaying efficiently. It uses a two level cache, first in-memory using an `LruCache“, then in disk, using DiskLruCache to save the files to the device’s SD Card. If an image is found in the memory cache, it is fetched from there, otherwise, it tries to retrieve it from disk cache. If it can’t be found either, then it finally downloads the image and stores it in both caches. Everything is done assynchonously, obviously. The library is still in early stage, as I plan to add more samples and polish it a bit more. So check out the Github repository.