Bitmap的高速加载

本文详细介绍Android中Bitmap类的功能,包括图片加载、缩放、裁剪等操作,以及使用BitmapFactory.Options配置项进行高效加载,防止内存溢出。同时,介绍了三种缓存策略:LruCache内存缓存、DiskLruCache硬盘缓存和SQLite数据库缓存,以提升应用响应速度并降低服务器负载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Bitmap的基本概念

  • Bitmap意为位图,是Android系统中的图像处理的最重要的类之一。
  • 通过Bitmap我们可以获取图片的相关信息
  • 获取到信息以后,可以对其进行缩放,裁剪等操作

Bitmap为我们提供了对于图像文件的操作

加载方法

Bitmap有4种加载方法:

1、字节数组:BitmapFactory.decodeByteArray()
2、文件路径:BitmapFactory.decodeFile()
3、资源ID:BitmapFactory.decodeResource()
4、流:BitmapFactory.decodeStream()

为什么要高效加载

  • 防止内存溢出
  • 尽可能的节省内存开销
  • 使得APP更加流畅

BitmapFactory.Options

属性:

  1. inJustDecodeBounds 标志位,是要加载图片,还是获取图片相关信息
  2. outWidth&outHeight 宽高
  3. inSampleSize 采样率

所以我们使用这个类的这几个属性来进行图片的裁剪:

package com.gin.xjh.bitmap;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class BitmapUtil {

    public static Bitmap ratio(String filePath, int piexlW, int piexlH) {
        BitmapFactory.Options newOptions = new BitmapFactory.Options();
        newOptions.inJustDecodeBounds = true;
        newOptions.inPreferredConfig = Bitmap.Config.RGB_565;//压缩质量参数
        //预加载
        BitmapFactory.decodeFile(filePath, newOptions);

        int originalW = newOptions.outWidth;
        int originalH = newOptions.outHeight;

        newOptions.inSampleSize = getSimpleSize(originalW, originalH, piexlW, piexlH);
        newOptions.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, newOptions);
    }

    private static int getSimpleSize(int originalW, int originalH, int piexlW, int piexlH) {
        int simpkeSize = 1;
        if (originalW > originalH && originalW > piexlW) {
            simpkeSize = originalW / piexlW;
        } else if (originalW < originalH && originalH > piexlH) {
            simpkeSize = originalH / piexlH;
        }
        if (simpkeSize <= 0) {
            simpkeSize = 1;
        }
        return simpkeSize;
    }

}

缓存

我们还有高效的加载的方法就是使用缓存,因为很多的图片是重复加载的,原来加载过的,所以我们可以去使用缓存机制来进行高效的加载
缓存的优势

  1. 对一些不是经常更新的数据可以使用本地缓存,提升应用响应速度
  2. 我们使用缓存就可以不用再频繁的请求服务器,可以降低服务器的负载压力

我们可以使用的缓存策略在Android中主要有下面三种

  • LruCache 实现内存缓存(在一些情况下会进行清除,如:内存不足)
  • DiskLruCache 实现硬盘缓存(外置存储中)
  • SQLite实现缓存(存储在数据库中)
LruCache

Lru是一种缓存算法,最近最少使用算法,LruCache采用的是LinkedHashMap。
使用LruCache实现网络图片缓存:

package com.gin.xjh.bitmap;

import android.graphics.Bitmap;
import android.util.LruCache;
import android.widget.ImageView;

public class SimpleImageLoader {

    private static SimpleImageLoader mLoader = null;

    private LruCache<String, Bitmap> mLruCache;

    public static SimpleImageLoader getInstance() {
        if (mLoader == null) {
            synchronized (SimpleImageLoader.class) {
                if (mLoader == null) {
                    mLoader = new SimpleImageLoader();
                }
            }
        }
        return mLoader;
    }

    /**
     * 初始化缓存对象
     */
    private SimpleImageLoader() {
        int maxSize = (int) (Runtime.getRuntime().maxMemory() / 8);
        mLruCache = new LruCache<String, Bitmap>(maxSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
            }
        };
    }

    /**
     * 加载网络图片
     */
    public void displayImage(ImageView view, String url) {
        Bitmap bitmap = getBitmapFromCache(url);
        if (bitmap != null) {
            view.setImageBitmap(bitmap);
        } else {
            downloadImage(view, url);
        }
    }

    /**
     * 从缓存中读取图片
     */
    private Bitmap getBitmapFromCache(String url) {
        return mLruCache.get(url);
    }

    /**
     * 将下载下来的图片保存到缓存中
     */
    private void putBitmapToCache(Bitmap bitmap, String url) {
        if (bitmap != null) {
            mLruCache.put(url, bitmap);
        }
    }

    /**
     * 下载图片,并且加载到缓存中
     */
    private void downloadImage(final ImageView imageView, final String url) {
        //进行图片的网络下载功能
        //在图片下载成功后调用
        Bitmap bitmap = null;
        putBitmapToCache(bitmap, url);
    }

}

对于图片从网络上下载下来的代码我就不写了,可以使用网上的很多网络请求的开源库,或者直接使用Android中自带的HttpURLConnection进行下载(如果不会使用可以看我上一篇博客:传送门

DiskLruCache

这个是由square团队开发的第三方的开源库,GitHub地址:https://github.com/JakeWharton/DiskLruCache
我们如何进行DiskLruCache的使用呢:

  1. 通过DiskLruCache.open去初始化一个缓存对象
  2. 通过DiskLruCache.get(String key)去获取到对应key下的缓存数据
  3. 通过DiskLruCache.Editor对象将数据保存到本地

并且因为DiskLruCache是放在外置存储中的,所以我们对于缓存路径要进行设置:

  • 有SDCard:/sdcard/Android/data/<application package>/cache
  • 无SDCard:/data/data/Android/data/<application package>/cache

这样的路径的原因是保证在APP下载后不会残留缓存文件在内存中。


GitHub地址:传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值