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

Android如何复用Bitmap或限制其数量 解决Picasso/Glide加载图片内存过高问题

一、现有代码首要优化点

  • ViewHolder视图缓存优化:你当前的setdetails方法每次绑定数据时都重复调用findViewById,虽然不直接导致内存暴涨,但会降低列表滑动性能,建议把mtitletv、mdesrcriptiontv、mlocationtv、mImagetv都提为ViewHolder的成员变量,在构造方法中只查找一次。示例修改如下:
public class HomeScreenWorkViewHolder  extends RecyclerView.ViewHolder {
    View view;
    DatabaseReference likeReference;
    public ImageView like_btn;
    public TextView like_text;
    // 新增视图成员变量
    public TextView mtitletv;
    public TextView mdesrcriptiontv;
    public TextView mlocationtv;
    public ImageView mImagetv;

    public HomeScreenWorkViewHolder(@NonNull View itemView) {
        super(itemView);
        like_btn = itemView.findViewById(R.id.like_btn);
        like_text = itemView.findViewById(R.id.like_text);
        // 构造方法中仅初始化一次视图
        mtitletv = itemView.findViewById(R.id.product_layout_name);
        mdesrcriptiontv = itemView.findViewById(R.id.product_layout_description);
        mlocationtv = itemView.findViewById(R.id.product_layout_location);
        mImagetv = itemView.findViewById(R.id.product_layout_image);
        view = itemView;
    }
    // 第二个带点击回调的构造方法同理补充视图初始化逻辑
}
  • 图片加载未做尺寸适配:你现在用Picasso加载图片时直接传入原图地址,没有根据ImageView的实际显示尺寸裁剪,会直接将全分辨率原图加载到内存,比如服务器返回20002000的原图,就算你的ImageView只有400400显示大小,也会占用16MB(ARGB_8888格式)内存,滑动十几条就会多占几百MB内存。修改Picasso加载代码如下:
Picasso.get()
    .load(image)
    .fit() // 自动将图片尺寸裁剪到ImageView的大小
    .centerCrop() // 按比例裁剪适配ImageView,不会拉伸
    .config(Bitmap.Config.RGB_565) // 不需要透明度的场景用RGB_565,内存占用减半
    .placeholder(R.drawable.ic_baseline_cloud_download_24)
    .into(mImagetv);

二、图片库全局配置优化

如果你主要用Picasso

  • 全局自定义Picasso配置,限制内存缓存大小和开启Bitmap复用,在Application的onCreate中初始化:
// 计算可用内存的1/8作为图片内存缓存上限
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
int cacheSize = maxMemory / 8;
Picasso.setSingletonInstance(new Picasso.Builder(this)
    .memoryCache(new LruCache(cacheSize))
    .defaultBitmapConfig(Bitmap.Config.RGB_565) // 全局默认用RGB_565
    .build());
  • 列表Item滑出屏幕时主动取消未完成的加载请求,在Adapter的onViewRecycled方法中添加:
@Override
public void onViewRecycled(@NonNull HomeScreenWorkViewHolder holder) {
    super.onViewRecycled(holder);
    Picasso.get().cancelRequest(holder.mImagetv); // 取消当前ImageView的加载请求,释放相关资源
}

如果你混用Glide

  • 不要同时用两个图片库加载同域名的图片,两个库的内存缓存、Bitmap复用池都是独立的,同一张图会被两份缓存占用双倍内存,建议统一用一个图片库。
  • Glide加载时优先传Activity/Fragment作为上下文,不要传Application上下文,这样页面销毁时Glide会自动清理当前页面的所有图片资源,释放内存。

三、RecyclerView额外优化

  • 增大RecyclerView的回收池大小,如果你列表的Item类型只有1种,可以设置:
recyclerView.getRecycledViewPool().setMaxRecycledViews(0, 20); // 缓存20个离屏Item,避免频繁创建ViewHolder
  • 如果列表图片很多,可以开启硬件加速,同时避免在Item中使用多层透明叠加,减少额外的内存开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:15:02