You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多次用Glide加载Bitmap至CropperImageView引发OOM问题求助

解决Glide加载Bitmap导致的OutOfMemory异常问题

我完全懂你遇到的麻烦——多次切换RecyclerView里的图片后,Glide因为加载高分辨率原图抛出OOM,这在处理手机拍摄的大尺寸图片时太常见了。下面是几个针对性的解决方案,按优先级排序:

1. 让Glide根据CropperImageView的实际尺寸缩放图片

这是最核心的优化点:相机拍摄的图片动辄几百万像素(比如你日志里的图片需要分配近50MB内存),但CropperImageView的实际显示尺寸远小于这个值,直接加载原图纯粹是浪费内存。

修改你的Glide加载代码,添加override()方法指定目标视图的宽高:

// 获取CropperImageView的实际显示尺寸
int targetWidth = cropperView.getWidth();
int targetHeight = cropperView.getHeight();

// 如果视图还未完成测量(比如页面刚初始化),用屏幕尺寸兜底
if (targetWidth == 0 || targetHeight == 0) {
    DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
    targetWidth = metrics.widthPixels;
    targetHeight = metrics.heightPixels;
}

Glide.with(getContext())
    .asBitmap()
    .load(imageFilePath)
    // 强制Glide将图片缩放到目标尺寸,大幅降低内存占用
    .override(targetWidth, targetHeight)
    // 保持图片比例,避免拉伸变形
    .fitCenter()
    .into(new SimpleTarget<Bitmap>() {
        @Override
        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
            // 先回收旧Bitmap,避免内存堆积
            Bitmap oldBitmap = cropperView.getBitmap();
            if (oldBitmap != null && !oldBitmap.isRecycled()) {
                oldBitmap.recycle();
            }
            cropperView.setImageBitmap(resource);
        }
    });

2. 替换SimpleTarget为ViewTarget(更推荐)

SimpleTarget如果没有妥善管理,容易引发内存泄漏或多余的内存占用。改用ViewTarget可以让Glide自动绑定视图生命周期,更安全高效:

Glide.with(getContext())
    .asBitmap()
    .load(imageFilePath)
    .override(targetWidth, targetHeight)
    .fitCenter()
    .into(new ViewTarget<CropperImageView, Bitmap>(cropperView) {
        @Override
        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
            Bitmap oldBitmap = this.view.getBitmap();
            if (oldBitmap != null && !oldBitmap.isRecycled()) {
                oldBitmap.recycle();
            }
            this.view.setImageBitmap(resource);
        }
    });

3. 配置Glide全局内存缓存与Bitmap池

在自定义的AppGlideModule里调整内存缓存和Bitmap池大小,让Glide更高效地复用Bitmap,减少重复内存分配:

@GlideModule
public class MyAppGlideModule extends AppGlideModule {
    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        // 取设备可用内存的1/8作为Glide内存缓存与Bitmap池的大小
        int memorySizeBytes = (int) (Runtime.getRuntime().maxMemory() / 8);
        builder.setMemoryCache(new LruResourceCache(memorySizeBytes));
        builder.setBitmapPool(new LruBitmapPool(memorySizeBytes));
    }
}

4. 页面销毁时清理资源

在页面的onDestroy()方法里,主动清理CropperImageView的Bitmap和Glide的加载任务,避免内存泄漏:

@Override
protected void onDestroy() {
    super.onDestroy();
    // 回收CropperImageView的Bitmap
    Bitmap bitmap = cropperView.getBitmap();
    if (bitmap != null && !bitmap.isRecycled()) {
        bitmap.recycle();
    }
    // 取消Glide所有未完成的加载任务
    Glide.with(this).clear(cropperView);
}

内容的提问来源于stack exchange,提问作者Fahime Ghasemi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:27:07