How does the Android Image Loading library use the bitmap pool for responsive UI?

Authors
  • Amit Shekhar
    Name
    Amit Shekhar
    Published on
How does the Android Image Loading library use the bitmap pool for responsive UI?

I am Amit Shekhar, a mentor helping developers in getting high-paying tech jobs.

In this blog, we are going to learn how the Android Image Loading library uses the bitmap pool to make the UI responsive.

This blog is a part of the series - "How does the Android Image Loading library work internally?"

  • How does the Android Image Loading library use the bitmap pool for responsive UI? - YOU ARE HERE
  • How does the Android Image Loading library solve the slow loading issue? - READ FROM HERE
  • How does the Android Image Loading library optimize memory usage? - READ FROM HERE

These concepts are important when it comes to Android Interviews.

So, I was reading the source code of various Image Loading libraries in Android like Glide, Fresco, etc.

These libraries do a lot of things internally for us so that we can just use them and get our tasks done easily. They make our life easier.

One of the things that they do is that they use the bitmap pool to make the UI responsive.

First, we need to understand why the UI becomes unresponsive.

The UI becomes unresponsive when our Android App lags. So, we need to understand why an Android App lags. Basically, there are two most important reasons as follows:

  • Garbage Collector(GC) running frequently
  • Doing too much work on the main thread

If you want to learn in deep about why an Android App lags, please read this blog and come back.

When we have a lot of images in our Android application, very frequently a number of images will be going out of view, and a number of new images will be coming into the view. This will lead to the continuous allocation and deallocation of memory in your application. It will lead to the GC running frequently and hence, unresponsive UI.

So the problem is that the bitmaps are larger in size, it makes the GC run frequently.

How does the Android Image Loading library solve the issue of unresponsive UI?

Answer: Bitmap Pool

These Image Loading libraries use the bitmap pool to reduce GC calls as much as possible and make the UI responsive.

By using the Bitmap pool, they avoid continuous allocation and deallocation of memory in our application and reduce GC overhead.

The next big question is: What is bitmap pooling?

Bitmap pooling is an implementation that tries to reuse the memory of the bitmaps already available instead of allocating new memory every time. Suppose we need to load a bitmap, we first check our pool to see if there is any bitmap available. If it is available, we take a bitmap from the pool and reuse its memory to load our new bitmap otherwise we create a new bitmap. In case, if we do not need any bitmap, we put that bitmap into that pool instead of recycling it so that we can reuse the memory of that bitmap when needed for a new bitmap.

We put constraints on the memory size of the pool as we put constraints on the memory size of a cache.

This is possible by using the inBitmap property of the Bitmap. (which reuses bitmap memory).

Let's say we have to load two bitmaps (bitmapOne, bitmapTwo) one by one. When we load bitmapOne, it will allocate the memory for bitmapOne. Then if when we no longer need bitmapOne, we do not recycle the bitmap (as recycling involves calling GC). Instead, we use this bitmapOne as an inBitmap for bitmapTwo. This way, the same memory can be reused for bitmapTwo.

Let's say, we are showing a bitmapOne into the imageView.

Bitmap bitmapOne = BitmapFactory.decodeFile(filePathOne);
imageView.setImageBitmap(bitmapOne);

Now, let's say, we do not need image bitmapOne and we have to set another bitmap in imageView.

final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePathTwo, options);
options.inMutable = true;
options.inBitmap = bitmapOne;
options.inJustDecodeBounds = false;
Bitmap bitmapTwo = BitmapFactory.decodeFile(filePathTwo, options);
imageView.setImageBitmap(bitmapTwo);

Note:

  • On API Level 19+, the Bitmap needs to be the same size or larger than the Bitmap that we are trying to decode. Otherwise, the Bitmap will be ignored and we will get a new Bitmap.
  • On older devices, the Bitmap needs to be the same size (resolution) as the Bitmap that we are trying to decode. Otherwise, the Bitmap will be ignored and we will get a new Bitmap.

This way we are not allowing the GC to be called again and again as we are not leaving off the reference of the bitmapOne, instead we are loading the bitmapTwo in the memory of bitmapOne.

These libraries create a bitmap pool of bitmaps.

We can say that the bitmap pool is a list of bitmaps that are no longer needed but are available for reuse to load the new bitmap into the same memory.

When any bitmap is available for recycling, these libraries just push the bitmap into that bitmap pool.

When these libraries have to load the new bitmap, they just get a bitmap that can be reused to load the new one to reuse the same memory from that bitmap pool. Hence no recycling, and no GC calls.

And we have responsive UI.

This was all about how the Android Image Loading library uses the bitmap pool to make the UI responsive.

We will learn more things that these libraries do in our upcoming blog post.

Master Kotlin Coroutines from here: Mastering Kotlin Coroutines

That's it for now.

Thanks

Amit Shekhar

You can connect with me on:

Read all of my high-quality blogs here.