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

App运行崩溃求助:点击MainScreen的ImageView跳转触发OutOfMemoryError

解决ImageView点击跳转时的OutOfMemoryError问题

嘿,我看你遇到了个头疼的问题:MainScreen页面的4个ImageView,本来点击要跳转到Category Activity传数据展示内容,结果一点击应用就崩了,Logcat里的OutOfMemoryError已经把根源指出来了——系统没法分配足够的内存,大概率是你加载的图片尺寸太大,把内存撑爆了。

先给你拆解下问题:报错里说要分配25600012字节(差不多24MB),这个大小对于单张图片来说已经很大了,如果你的ImageView直接加载原图,再加上跳转后Category Activity里的ListView又要加载一批图片,内存肯定扛不住。

下面给你几个实用的解决方案,按优先级来:

1. 优先用图片加载库优化图片加载

别自己手动硬扛图片内存管理了,用Glide或者Picasso这类成熟的图片加载库,它们会自动帮你压缩图片、做内存缓存和磁盘缓存,还能处理生命周期,大大降低OOM的概率。比如用Glide加载图片的代码很简单:

// 在MainScreen的Activity里
ImageView breakfastImg = findViewById(R.id.breakfast_img);
Glide.with(this)
     .load(R.drawable.breakfast_banner) // 你的图片资源
     .into(breakfastImg);

同样,在Category Activity的ListView Adapter里,也用Glide来加载列表项里的图片,不要直接用BitmapFactory加载原图。

2. 手动压缩图片(如果不想用第三方库)

要是你不想引入第三方库,那得手动对图片进行采样压缩,只加载ImageView实际需要的尺寸,而不是原图的完整尺寸。这里给你一个现成的工具方法:

// 工具类里的方法
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                     int reqWidth, int reqHeight) {
    // 先获取图片的原始尺寸,不加载到内存
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
    
    // 计算压缩比例
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
    // 加载压缩后的图片
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
        final int halfHeight = height / 2;
        final int halfWidth = width / 2;
        // 找到最大的2的幂数,保证压缩后的图片尺寸不小于目标尺寸
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

使用的时候,先获取ImageView的实际宽高,再加载压缩后的图片:

ImageView dinnerImg = findViewById(R.id.dinner_img);
// 获取ImageView的目标宽高(如果布局里是wrap_content,可能需要先测量)
int targetWidth = dinnerImg.getMeasuredWidth();
int targetHeight = dinnerImg.getMeasuredHeight();
Bitmap compressedBitmap = decodeSampledBitmapFromResource(getResources(), R.drawable.dinner_banner, targetWidth, targetHeight);
dinnerImg.setImageBitmap(compressedBitmap);

3. 优化Category Activity的ListView

跳转后的页面也不能掉以轻心:

  • 一定要复用ListView的convertView,避免每次创建新的Item视图,减少内存占用;
  • 列表项里的图片同样要做压缩处理,或者用图片加载库加载;
  • 如果列表里图片很多,可以考虑用RecyclerView代替ListView,它的内存管理更高效。

4. 临时应急方案(不推荐长期依赖)

要是上面的优化都做了还是有问题,可以在AndroidManifest.xml里给应用开启大内存堆,但这只是临时办法,治标不治本:

<application
    android:name=".YourApp"
    android:largeHeap="true">
    <!-- 其他配置 -->
</application>

最后再提醒下:OOM大多是内存管理不当导致的,优先从图片压缩、视图复用这些根源问题入手解决,别依赖大内存堆哦~

内容的提问来源于stack exchange,提问作者Hussein Nd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:41:56