This is the beginning of what I hope will be a handful of useful articles for anyone working with Bitmaps on Android.
This is a bit of a silly (but a real) one to start with but it’s definitely worth checking what resources you have lying around in your /res folder, which particular drawable folder they are in and what size they are.
In a lot of cases you can put a high quality version of your image resource in the ‘drawable-xxhdpi’ or ‘drawable-xxxhdpi’ folder and let the Android operating system do it’s ‘magic’ and scale the image for you. Any images you don’t want scaled can be put into a ‘drawable-nodpi’ folder.
On one app that I work on, we recently updated an activity that shows contact information for a contact that you tap on. It’s a standard use case: User sees a list of contacts, user taps on a chosen contact, a new screen (activity) pops up to show information for that user. We decided to move towards the more modern, material design for this activity and used the CollapsingToolbarLayout (http://antonioleiva.com/collapsing-toolbar-layout/). We had a green background image that we used in other locations in the app and so we used it for our image here as well.
A few weeks later we saw crashes on devices ranging from ‘low memory’, old Samsung’s to the latest Nexus 6P when users opened this activity. Looking into it showed at least 3–5 seconds delay when opening the contact info activity on numerous test devices. After removing everything from the onCreate() method and still seeing the delay, it became obvious that something in the layout was the issue, and once we got more info on the crashes and saw OutOfMemory exceptions it became clear that the ImageView was causing the issue.
Ultimately, the background image that we used was ~250k in size (seemingly nothing but remember we’re working with limited resources here and the bitmap size in-memory will always be larger than the file size); More importantly it was placed in the /drawable folder. The OS was scaling the image but treating it as mdpi, so the image was being scaled up from there which was causing the OOM exception (thanks to patloew on androiddev sub-reddit for the correction).
Once I moved the image to the ‘drawable-xxhdpi’ folder, this both fixed the OOM issue and tapping on a contact opened the info activity seemingly instantaneously.
I’m not saying that this is the best way to handle your resources; In reality the best way is to provide multiple scaled versions of your resources as expected but you decide what is best for your app.