前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Using Bitmap Pools in Android

Using Bitmap Pools in Android

作者头像
用户9732312
发布2022-05-13 18:07:57
3270
发布2022-05-13 18:07:57
举报
文章被收录于专栏:ADAS性能优化

Image heavy applications have to decode many images, so there will be continuous allocation and deallocation of memory in application. This results in frequent calling of the Garbage Collector (GC). And if you call the GC too many times, your application UI freezes.

Glide , Fresco and Android Networking all use the Bitmap Pool Concept to load images efficiently.

代码语言:javascript
复制
GET RID OF : GC_FOR_ALLOC freed 1568K, 23% free 37664K/48844K, paused 141ms, total 143ms - (whenever you see this log , your application is lagging)

By using the Bitmap pool to avoid continuous allocation and deallocation of memory in your application, you reduce GC overhead, which results in a smooth-running application.

One way to do this is to use inBitmap (which reuses bitmap memory).

Suppose we have to load few bitmaps in an Android application.

When we load bitmapOne, it will allocate the memory for bitmapOne.

Then if when we no longer need bitmapOne, do not recycle the bitmap (as recycling involves calling GC). Instead, use this bitmapOne as an inBitmap for bitmapTwo. This way, the same memory can be reused for bitmapTwo.

代码语言:javascript
复制
Bitmap bitmapOne = BitmapFactory.decodeFile(filePathOne);
imageView.setImageBitmap(bitmapOne);
// lets say , we do not need image bitmapOne now and we have to set // another bitmap in imageView
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePathTwo, options);
if (canUseForInBitmap(bitmapOne, options)) { 
//canUseForInBitmap check if the image can be reuse or not by //checking the image size and other factors
    options.inMutable = true;
    options.inBitmap = bitmapOne;
}
options.inJustDecodeBounds = false;
Bitmap bitmapTwo = BitmapFactory.decodeFile(filePathTwo, options);
imageView.setImageBitmap(bitmapTwo);
代码语言:javascript
复制
public static boolean canUseForInBitmap(
        Bitmap candidate, BitmapFactory.Options targetOptions) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        // From Android 4.4 (KitKat) onward we can re-use if the byte size of
        // the new bitmap is smaller than the reusable bitmap candidate
        // allocation byte count.
        int width = targetOptions.outWidth / targetOptions.inSampleSize;
        int height = targetOptions.outHeight / targetOptions.inSampleSize;
        int byteCount = width * height * getBytesPerPixel(candidate.getConfig());

        try {
            return byteCount <= candidate.getAllocationByteCount();
        } catch (NullPointerException e) {
            return byteCount <= candidate.getHeight() * candidate.getRowBytes();
        }
    }
    // On earlier versions, the dimensions must match exactly and the inSampleSize must be 1
    return candidate.getWidth() == targetOptions.outWidth
            && candidate.getHeight() == targetOptions.outHeight
            && targetOptions.inSampleSize == 1;
}
代码语言:javascript
复制
private static int getBytesPerPixel(Bitmap.Config config) {
    if (config == null) {
        config = Bitmap.Config.ARGB_8888;
    }

    int bytesPerPixel;
    switch (config) {
        case ALPHA_8:
            bytesPerPixel = 1;
            break;
        case RGB_565:
        case ARGB_4444:
            bytesPerPixel = 2;
            break;
        case ARGB_8888:
        default:
            bytesPerPixel = 4;
            break;
    }
    return bytesPerPixel;
}

So, we are reusing the memory of bitmapOne while decoding bitmapTwo.

InBitmap works here.

So inBitmap is important here.

Similarly , while implementing it in listview, recyclerview — we will be able to get smooth scrolling. Glide and Fresco load the image smoothly by using this bitmap pool concept.

Without Bitmap Pool, there will be flickering and lagging in UI while scrolling.

In this way, we can avoid continuous allocation and deallocation of memory in application, reduce the GC overhead, and maintain a smooth-running application.

But there’s one problem: there are a few restrictions for using BitMap Pools in versions of Android that are older than Honeycomb. And only few android version older than Kitkat will only allow us to use inSampleSize = 1. But any version newer than KitKat will support BitMap with only a few minor issues.

So, all these types of cases are handled in this library Glide Bitmap Pool, which you can use to optimize your Android application.

As all the cases are handled in this library, you just have to decode images using this library, and recycle these image using this library. There’s no need to handle version-wise cases.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android性能优化 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档