android图片优化

在 Android 中加载大图时,如果不进行优化处理,很容易导致内存溢出(OOM)和应用卡顿。以下是几种高效处理大图加载的方法和最佳实践:


1. 使用图片加载库(推荐)

成熟的第三方库已经处理了内存管理、缓存和异步加载等问题,推荐使用:

  • Glide
    Glide.with(context)
        .load(imageUrl)
        .override(targetWidth, targetHeight) // 指定加载尺寸
        .diskCacheStrategy(DiskCacheStrategy.ALL) // 缓存优化
        .into(imageView)
    
  • Picasso
    Picasso.get()
        .load(imageUrl)
        .resize(targetWidth, targetHeight) // 缩放图片
        .centerInside() // 保持比例
        .into(imageView)
    
  • Coil(Kotlin 协程支持)
    imageView.load(imageUrl) {
        size(targetWidth, targetHeight)
        memoryCachePolicy(CachePolicy.ENABLED)
    }
    

2. 手动压缩图片(Bitmap 优化)

如果必须直接操作 Bitmap,需通过以下步骤减少内存占用:

(1) 获取图片尺寸(不加载内存)
val options = BitmapFactory.Options().apply {
    inJustDecodeBounds = true // 只解码边界信息
}
BitmapFactory.decodeFile(imagePath, options)
val (width, height) = options.outWidth to options.outHeight
(2) 计算缩放比例(inSampleSize)
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
    val (height, width) = options.outHeight to options.outWidth
    var inSampleSize = 1

    if (height > reqHeight || width > reqWidth) {
        val halfHeight = height / 2
        val halfWidth = width / 2
        // 计算最大 inSampleSize 保证缩放后尺寸仍大于目标值
        while (halfHeight / inSampleSize >= reqHeight && 
               halfWidth / inSampleSize >= reqWidth) {
            inSampleSize *= 2
        }
    }
    return inSampleSize
}
(3) 加载压缩后的 Bitmap
val options = BitmapFactory.Options().apply {
    inSampleSize = calculateInSampleSize(/* 目标尺寸 */)
    inPreferredConfig = Bitmap.Config.RGB_565 // 减少内存(每个像素占2字节)
}
val bitmap = BitmapFactory.decodeFile(imagePath, options)
imageView.setImageBitmap(bitmap)

3. 分块加载超大图(区域解码)

对于超大型图片(如地图、高清壁画),使用 BitmapRegionDecoder 分区域加载:

val decoder = BitmapRegionDecoder.newInstance(inputStream, false)
val rect = Rect(startX, startY, endX, endY) // 目标区域坐标
val options = BitmapFactory.Options().apply {
    inPreferredConfig = Bitmap.Config.RGB_565
}
val regionBitmap = decoder.decodeRegion(rect, options)
imageView.setImageBitmap(regionBitmap)

4. 内存管理技巧

  • 及时回收 Bitmap
    if (!bitmap.isRecycled) {
        bitmap.recycle() // 主动释放 Native 内存
    }
    
  • 使用 WeakReference:避免 Activity 泄漏。
  • 开启大堆(谨慎使用)
    AndroidManifest.xml 中为 Activity 添加:
    <application android:largeHeap="true">
    

5. 其他优化策略

  • 磁盘缓存:避免重复解码。
  • 列表中使用缩略图:如 RecyclerView 优先加载低分辨率图。
  • 监听生命周期:在 onDestroy 中取消加载(Glide 自动支持)。

总结流程图

加载图片 → 检查缓存 → 计算目标尺寸 → 缩放/分块解码 → 显示
           ↑
        (内存/磁盘缓存)

通过合理使用库或手动优化,可以高效加载大图而不影响性能。推荐优先选择 GlideCoil,它们已封装了绝大多数优化逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值