Free Android app covering all aspects of addiction, including prevention and treatment

Using Bitmaps efficiently

  • Written by  Clive

Using Images without killing your app

Android Bitmaps picasso list icon

Images take time to download and display. They can make your app unresponsive, especially when using them in list views, grid views and view pagers.

The solution is to download and process them off the main thread. Then resize and cache them for faster loading.

This takes quite a bit of coding, but there’s a simpler solution!

This tutorial will show you how to use the (FREE) Picasso Library to take care of everything for you. You just add one line of code! It couldn’t be easier!

What are bitmaps?

Images come in two flavours, Vector Graphics and Bitmaps. Bitmap images are stored as a map of bits, sometimes also referred to as a map of pixels.

You may want to read Designing for multiple screens. Alternative image resources, for more on using images in your apps.

Images also come in different sizes. Bigger images have more pixels so they take up more space. They also take longer to download and to display.

It’s all about Memory

Android devices have a limited amount of memory which has to be shared amongst the operating system and the apps running on the device.

Bigger images use more memory and can make your app unresponsive.

There are techniques that you can use when working with images to make them load faster:

  • Scale down - Put a smaller version of the original in memory
  • Do all the processing of the image off the main thread
  • Recycle image views and take care of processing images at the same time
  • Save your images in a cache for faster reloading. Use both a memory and a disc cache

There are two ways of doing this:

  • Do it all yourself
  • Use a library that takes care of it for you

Doing it yourself

Check out the documentation. There’s quite a bit of coding involved.

Loading large Bitmaps efficiently

Processing Bitmaps off the UI thread

Caching Bitmaps

Managing Bitmap memory

Displaying Bitmaps in your UI

Let the Picasso Library do it for you

There are a few image processing libraries to choose from. At the time of writing, Picasso seems to be one of the best so we’re using it in our tutorial app.

If you’ve checked out the code in the links above, you’d have seen that there is quite a lot of coding involved. Enter Picasso!

In Picasso it’s all taken care of in ONE SINGLE LINE OF CODE. Seriously!

Picasso

Picasso is a powerful image downloading and caching library package which you include in your app build. It simplifies working with images, reducing the code that you need to use to one line of code.

Picasso is fast and easy to use.

Picasso takes care of all your image processing for you. It can also download images.

So what can Picasso do for you?

  • You can download single images or many if used inside an adapter. It automatically detects adapter reuse and cancels the download. It’s done on a separate thread too
  • You can load your images from Content providers, assets, files and resources
  • You can transform your images by resizing and cropping them with minimal memory use
  • You can include download and error placeholders
  • Your images are automatically cached in memory and on disc. Different transformations of the same image can be stored for future use
  • Any unused image views are automatically recycled
  • Your images are displayed in your image views
  • You can also display a colour marker while developing. Useful if you want to see where your image is being loaded from (memory or disc)

Oh, and did I mention it’s free and Open Sourced?

Check out the Picasso website

The tutorial app

Our tutorial app displays a list of items. Each item includes an image and a line of text. The user can select an item which displays a larger image with some extra text.

The images are loaded from a drawables folder.

Android Bitmaps picasso list screen1

The list items display an image and some text

Note the following:

  • The original image has been scaled down in size so that it can be included in the list
  • While developing, you can display a small colour triangle in the top-left corner of the image. This indicates where the image is being loaded from:
    • Green – loaded from memory
    • Yellow – loaded from disc

Android Bitmaps picasso list screen2

Selecting the Golden Silence item displays a larger image and some text. This image has been loaded from the disc

Android Bitmaps picasso list screen3

Selecting the item again, loads the image from the memory cache

The Main activity

The main activity displays a list of items. The items include both an image and some text. Selecting an item displays a larger image and some text detail in a fragment.

Each item is created using a person class.

The Person class

The fields in the class are:

  • Name – String
  • Image resource id – int
  • A phrase – String
  • Phone number - int

Populating the list

To populate our list, we first create a Person list object, people:

Android Bitmaps picasso list peopleList

Our list consists of an array list of Person objects

We use our populatePersonList() method to populate the list:

Android Bitmaps picasso populatePerson

We add our Person objects to the list in the populatePersonList() method

Note the following:

  • Add – adds the Person object to the end of the people list

Our List layout

Android Bitmaps picasso listLayout

Our main activity’s layout includes a ListView view which takes care of displaying the scrolling list

Populating the list view

We populate the list view in the populateListView() method:

Android Bitmaps picasso populateListView

Our custom ArrayAdapter populates our list view using the items in our people list

Note the following:

  • adapter  - an instance of our custom array adapter
  • list – our list view which displays the list in the main activity. It’s in the activity_main.xml file
  • setAdapter – we set the adapter to be used to supply the data to the list view

Creating our custom adapter

We create our own adapter to supply our image and text to the list.

Here’s the code:

Android Bitmaps picasso custom ArrayAdapter

We create our custom ArrayAdapter MyListAdapter and return a view for each item

Note the following:

  • we use the item_view.xml layout to display each item row in the list. This is where you can customise the look of each row
  • getView – this gets a view to display each item in the list. It has three parameters:
    • position – the position of the item in the adapter. It’s this item’s view that we want to display
    • convertView – an old view that we may be able to re-use
    • parent – this is the parent list view that will display this item view
  • itemView – this is the item view that we will return and display in the list. We try and re-use the convertView if possible. Otherwise we create a new item view by inflating the item_view.xml layout file
  • currentPerson – we get an instance of the list item identified by its position in the list
  • ImageView – we get an instance of the image view. We’ll use it to display the thumbnail image in the list
  • nameText – we get an instance of the text view. This will display the name string
  • return itemView – we return the item view. This will display this item in the main list
  • Picasso – this takes care of getting the image, resizing it, storing it in both memory and disc cache and making it available for display. It also takes care of recycling the image views no longer used
  • setDebugging – used in development. If true, a colour triangle will display in the top-left corner of the image. Yellow indicates that the image was loaded from disc while green indicates that it was loaded from memory

We’re using the Picasso library which you must include in your build. Have a look at Loading the Picasso Library into your app build to see how to do that.

Selecting an item

When a user selects an item, we display a full image and some text in a fragment.

You may want to look at Dynamic layouts using fragments for more on fragments.

Here’s the code that takes care of the item selection:

Android Bitmaps OnItemClick

Selecting an item gets the details of that item. These are passed on to a new activity which creates and displays a fragment containing the details

Note the following:

  • We attach the listener to our list view
  • The onItemClick() method is executed when an item is selected
  • clickedPerson – we use the position parameter to identify which list item was selected
  • get<type> - we use the get<type> () method to get the relevant values for the selected item
  • intent – we create a new Intent which we’ll use to start the DetailsFragmentActivity activity
  • putExtra – we put the values into the intent. We’ll use these values when we create the fragment
  • startActivity – we start the DetailsFragmentActivity activity

Check out Passing data between activities for more on using intents to pass data to activities.

The Fragment

We use a fragment to display the full image and extra text detail for the selected item. The fragment is created by and displayed in the details fragment activity.

The details fragment activity

The details fragment activity creates and displays a fragment containing the details of the selected item.

We get the selected item’s data out of the intent that started the activity. Then we put the data into the new fragment object.

Here’s the main bit of code:

Android Bitmaps Fragment Activity

We create a new fragment, passing it the selected item’s details

Note the following:

  • args – a Bundle object that we put our selected item’s details into
  • put<type> - we use the put<type>() method to put our data into the bundle
  • setArguments – we put the bundle into the fragment object
  • getSupportFragmentManager – we’re using the Support Library so we get an instance of the fragment manager using getSupportFragmentManager
  • replace – we replace whatever’s showing in the container with our new fragment

The fragment’s layout

The DetailsFragmentActivity activity’s layout contains the fragment’s container FrameLayout view:

Android Bitmaps Fragment container

Our fragment’s container view

The Details fragment

The details fragment displays the selected item’s details in a new fragment.

Here’s the one line of code needed to get the image, resize, crop and then display it in the image view. It also takes care of caching the image in both memory and disc and recycling the unused image views:

Android Bitmaps Picasso

One line does it all: loads, resizes, transforms, caches and displays the image

Note the following:

  • with – the context of the Picasso instance
  • load – we’re using a drawable resource. You could also pass an URl, File or file path
  • resize – resamples the image to produce the required size
  • centerCrop – resizing the image to fit the required size and then crops the excess
  • into – asynchronously loads the image into the image view. It also recycles the image views no longer used

You can change the configuration of the default Picasso instance if you want. Check out the Picasso documentation

You may want to have a look at our GridView tutorial where we used Picasso to handle the images: GridView tutorial using the Picasso Library

I hope that you have found this tutorial helpful.

If you need more info on ArrayAdapters and lists, have a look at our Android ListView tutorial.

You can download the project files here Download icon