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

RecyclerView中使用Fresco仍出现OOM问题求助

解决RecyclerView中使用Fresco仍出现OOM的问题

遇到在RecyclerView里切换到Fresco还是遭遇OOM的情况确实挺闹心的,我结合实际开发经验给你几个针对性的排查和解决方向:

  • 自定义Fresco内存缓存配置,限制内存占用
    Fresco默认的内存缓存设置可能在内存紧张的设备上还是会占用过多资源。你可以在初始化Fresco时手动调整内存缓存的上限,比如设置为应用最大可用内存的1/8:

    ImagePipelineConfig config = ImagePipelineConfig.newBuilder(context)
        .setBitmapMemoryCacheParamsSupplier(() -> {
            int maxCacheSize = (int) (Runtime.getRuntime().maxMemory() / 8);
            return new MemoryCacheParams(
                maxCacheSize,
                Integer.MAX_VALUE,
                maxCacheSize,
                Integer.MAX_VALUE,
                Integer.MAX_VALUE);
        })
        .build();
    Fresco.initialize(context, config);
    

    这样能避免Fresco的内存缓存无限制膨胀,减少OOM风险。

  • 强制压缩图片到View实际尺寸
    很多OOM都是因为加载了远大于View显示尺寸的原图导致的。你可以在构建ImageRequest时添加ResizeOptions,让Fresco自动把图片压缩到View的大小:

    // 注意:确保holder.image已经完成测量,能拿到正确的宽高
    ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(item.getImageUrl()))
        .setResizeOptions(new ResizeOptions(holder.image.getWidth(), holder.image.getHeight()))
        .setLocalThumbnailPreviewsEnabled(true)
        .build();
    
    DraweeController controller = Fresco.newDraweeControllerBuilder()
        .setImageRequest(request)
        .setOldController(holder.image.getController())
        .setAutoPlayAnimations(true)
        .build();
    holder.image.setController(controller);
    

    如果在onBindViewHolder时View还没完成测量,你可以通过ViewTreeObserver监听测量完成事件后再设置请求,或者根据布局预估一个合理的尺寸。

  • 在ViewHolder回收时主动释放资源
    确保RecyclerView的ViewHolder被回收时,Fresco的控制器也能及时释放。重写onViewRecycled方法:

    @Override
    public void onViewRecycled(@NonNull ViewHolder holder) {
        super.onViewRecycled(holder);
        // 断开控制器,释放相关内存资源
        holder.image.setController(null);
    }
    
  • 排查其他内存泄漏点
    有时候OOM不一定是Fresco的锅,你可以用Android Studio的Profiler工具生成内存快照,分析是否有其他长生命周期对象(比如上下文、回调)被ViewHolder或数据项持有导致内存泄漏。

  • 尝试关闭硬件加速(最后备选)
    部分设备上的硬件加速可能会导致额外的内存开销,你可以给DraweeView关闭硬件加速试试:

    <!-- 在布局中设置 -->
    <com.facebook.drawee.view.SimpleDraweeView
        ...
        android:hardwareAccelerated="false" />
    

    或者在代码中设置:

    holder.image.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    

    这个操作可能会影响图片加载性能,建议只在其他方案无效时尝试。

  • 更新到最新版Fresco
    旧版本的Fresco可能存在已知的内存泄漏bug,升级到最新的稳定版本说不定能直接解决问题。

内容的提问来源于stack exchange,提问作者Sourav Nag

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:02:09