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

Android应用专辑封面无法显示问题求助

解决Android专辑封面加载失败及相关日志问题

看起来你遇到了几个关联的问题,咱们一步步来拆解解决:

1. 先处理日志里的两个基础问题

「No adapter attached; skipping layout」错误

这个错误说明你的RecyclerView在布局渲染的时候还没有绑定Adapter。正确的做法是先初始化空Adapter并设置给RecyclerView,之后再加载数据更新:

// 在Fragment/Activity的初始化代码里(比如onCreateView/onCreate)
_songs = new ArrayList<>();
songAdapter adapter = new songAdapter(getContext(), _songs);
recyclerView.setAdapter(adapter);
// 之后再调用加载数据的方法

「Skipped 51 frames!」主线程阻塞问题

你直接在主线程里查询MediaStore,这会阻塞UI线程导致卡顿。必须把数据查询放到后台线程,用AsyncTask(Java)来处理,示例代码如下:

private class LoadSongsTask extends AsyncTask<Void, Void, ArrayList<songInfo>> {
    @Override
    protected ArrayList<songInfo> doInBackground(Void... voids) {
        ArrayList<songInfo> songs = new ArrayList<>();
        Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
        String[] projection = {
            MediaStore.Audio.Media.DISPLAY_NAME,
            MediaStore.Audio.Media.ARTIST,
            MediaStore.Audio.Media.DATA,
            MediaStore.Audio.Media.ALBUM_ID
        };
        Cursor cursor = getContext().getContentResolver().query(uri, projection, selection, null, null);
        if (cursor != null) {
            int albumIdColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID);
            if (cursor.moveToFirst()) {
                do {
                    String name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
                    String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
                    String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
                    long albumId = cursor.getLong(albumIdColumn);
                    songs.add(new songInfo(name, artist, url, albumId));
                } while (cursor.moveToNext());
            }
            cursor.close();
        }
        return songs;
    }

    @Override
    protected void onPostExecute(ArrayList<songInfo> songs) {
        super.onPostExecute(songs);
        _songs.clear();
        _songs.addAll(songs);
        recyclerView.getAdapter().notifyDataSetChanged();
    }
}

// 调用方式
new LoadSongsTask().execute();

2. 专辑封面加载失败的核心问题

这是你最头疼的问题,主要有两个关键错误:

错误1:存错了ID!

你在loadSongs里把歌曲的ID当成专辑ID存进了songInfo,这完全不对!应该获取MediaStore.Audio.Media.ALBUM_ID:

// 修改loadSongs里的专辑ID获取代码
int albumIdColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID);
long albumId = cursor.getLong(albumIdColumn);

错误2:直接把ID转成路径是无效的

专辑ID不是文件路径,你需要通过专辑ID构造对应的Content Uri,或者查询专辑表获取封面路径。最省心的方式是用Glide这类图片加载库,它们能直接处理Content Uri,还自带缓存和错误处理:

// 在Adapter的onBindViewHolder里替换封面加载代码
Uri albumArtUri = ContentUris.withAppendedId(
    MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, 
    s.getAlbum_art() // 现在这个是正确的专辑ID了
);
Glide.with(context)
     .load(albumArtUri)
     .placeholder(R.drawable.your_default_cover) // 加载中的占位图
     .error(R.drawable.your_default_cover) // 加载失败时显示的图
     .into(songHolder.album_art);

记得先在app的build.gradle里添加Glide的依赖:

implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'

额外优化:修复Adapter的点击事件

你原来在onBindViewHolder里每次都设置setOnItemClickListener,这会导致重复绑定,效率很低。改成直接给ViewHolder的itemView设置点击事件:

// 在Adapter的onBindViewHolder里
songHolder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mOnItemClickListener != null) {
            mOnItemClickListener.onItemClick(songHolder, v, s, i);
        }
    }
});

然后把原来的setOnItemClickListener调用移到Adapter外部(比如你的Fragment/Activity里),这样才是正确的用法。

最后总结修改步骤

  1. 提前给RecyclerView设置空Adapter
  2. 把数据查询逻辑移到AsyncTask后台线程
  3. 修正专辑ID的获取方式,存正确的ALBUM_ID
  4. 用Glide加载专辑封面,替换原来的错误路径转换
  5. 修复Adapter的点击事件绑定逻辑

按照这些步骤修改后,你的专辑封面应该能正常显示,日志里的错误也会消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:10:07