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

RecyclerView加载本地歌曲滚动卡顿,如何优化Glide加载?

问题描述

我开发了一个从内存加载歌曲列表的RecyclerView,滚动时存在卡顿问题,仅在每次打开应用后的首次滚动时出现。移除Glide图片加载逻辑后,卡顿现象完全消失。

以下是我的onBindViewHolder实现代码:

override fun onBindViewHolder(holder: MyHolder, position: Int) {
        holder.titleView.text = musicList[position].title
        holder.albumName.text = musicList[position].artist
        holder.duration.text = formatDuration(musicList[position].length)
        Glide
            .with(context)
            .load(musicList[position].artUri)
            .diskCacheStrategy(DiskCacheStrategy.ALL)
            .apply(RequestOptions().placeholder(R.drawable.image_as_cover).centerCrop())
            .into(holder.imageView)
        holder.itemView.setOnClickListener {
            if (MainActivity.isSearching)
                sendIntent(position = position, parameter = "MusicAdapterSearch")
            else
                sendIntent(position = position, parameter = "MusicAdapter")
        }
    }

对应列表项的XML布局代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:theme="@style/Theme.Music.Font">

    <com.google.android.material.imageview.ShapeableImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentStart="true"
        android:layout_margin="5dp"
        android:contentDescription="@string/cover"
        android:src="@drawable/image_as_cover"
        app:shapeAppearance="@style/roundedImageView" />

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toStartOf="@+id/duration"
        android:layout_toEndOf="@+id/imageView"
        android:orientation="vertical">

        <TextView
            android:id="@+id/titleView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:fontFamily="@font/medium"
            android:maxLines="1"
            android:singleLine="true"
            android:text="@string/love_is_gone_by_slander_forever_on_love"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/albumName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:fontFamily="@font/medium"
            android:maxLines="1"
            android:text="@string/albumName"
            android:textSize="12sp"
            android:theme="@style/Theme.Music.FontColor" />
    </LinearLayout>

    <TextView
        android:id="@+id/duration"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true"
        android:layout_margin="10dp"
        android:fontFamily="@font/medium"
        android:maxLines="1"
        android:text="@string/duration"
        android:textSize="11sp" />

</RelativeLayout>

请问该如何解决此卡顿问题,是否需要更换图片加载库或调整缓存相关策略?


解决方案

不需要更换图片加载库,Glide本身已是优化成熟的图片加载框架,问题出在首次加载的缓存与图片处理策略上,调整以下几点即可解决:

  • 预加载专辑封面
    在应用启动阶段(比如MainActivity的onCreate),提前用Glide加载一批常用的专辑封面到内存缓存,避免首次滚动时才触发加载操作。示例代码:

    // 在初始化时机执行,比如MainActivity.onCreate
    musicList.take(20).forEach { music ->
        Glide.with(this)
            .load(music.artUri)
            .diskCacheStrategy(DiskCacheStrategy.ALL)
            .preload(50,50) // 对应列表项中图片的实际尺寸
    }
    
  • 优化Glide加载配置

    1. 明确指定图片加载尺寸,避免Glide自动计算尺寸时的额外性能开销:将.centerCrop()替换为.override(50,50).centerCrop(),尺寸与布局中ShapeableImageView的宽高保持一致。
    2. 显式启用内存缓存(Glide默认开启,但显式声明可确保逻辑清晰),添加.skipMemoryCache(false),让首次加载后的图片存入内存,后续滚动直接读取缓存。
      修改后的Glide加载代码:
    Glide
        .with(context)
        .load(musicList[position].artUri)
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .override(50, 50) // 匹配布局中ImageView的尺寸
        .centerCrop()
        .placeholder(R.drawable.image_as_cover)
        .skipMemoryCache(false)
        .into(holder.imageView)
    
  • 优化布局渲染性能

    1. 将RelativeLayout替换为ConstraintLayout,相对布局的测量与布局开销在列表场景中更高,约束布局能更高效地处理视图间的位置关系。
    2. 给ShapeableImageView添加android:hardwareAccelerated="true"属性,启用硬件加速提升圆角裁剪的渲染效率。
  • 避免主线程耗时操作
    检查formatDuration方法是否在主线程执行了耗时计算,如果是,提前在子线程批量格式化所有歌曲的时长并存入musicList,避免在onBindViewHolder中重复执行计算逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:10:31