如何在游标适配器中使用 AsyncTask 加载 albumArt

How to load albumArt using AsyncTask in cursor adapter

我在使用游标适配器中的 AsyncTask 检索 albumArt 并将该艺术设置为 ImageView 时遇到问题。 当我打开我的应用程序时,它看起来像这样:

然后我向下滚动列表,一切都很好(但如果我滚动列表不是很快):

然后我将列表滚动回最开始(不是很快),它看起来也不错:

可能我做错了什么,我想,所以我有问题:

是否有可能以某种方式解决该问题,我已经尝试了很多不同的方法来实现 AsyncTask 并使其正常工作,但最终它看起来总是一样。

下面是游标适配器的代码:

public class AllSongsCursorAdapter extends CursorAdapter {

public AllSongsCursorAdapter(Context context, Cursor cursor) {
    super(context, cursor, 0);
}

public boolean isCheckBoxVisible;
private AddToFavouritesArray favouritesArray = AddToFavouritesArray.getInstance();

private static class ViewHolder {
    CheckBox checkBox;
    TextView title;
    TextView artist;
    ImageView albumArt;

    private ViewHolder(View view) {

        checkBox = (CheckBox) view.findViewById(R.id.favouritesCheckBox);
        title = (TextView) view.findViewById(R.id.title);
        artist = (TextView) view.findViewById(R.id.artist);
        albumArt = (ImageView) view.findViewById(R.id.albumArt);
    }
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
    View view = LayoutInflater.from(context).inflate(R.layout.song_item, viewGroup, false);
    ViewHolder viewHolder = new ViewHolder(view);
    view.setTag(viewHolder);
    return view;
}

@Override
public void bindView(View view, Context context, final Cursor cursor) {

    final ViewHolder viewHolder = (ViewHolder) view.getTag();
    if (isCheckBoxVisible) {
        viewHolder.checkBox.setVisibility(View.VISIBLE);
    } else {
        viewHolder.checkBox.setVisibility(View.GONE);
    }

    final int position = cursor.getPosition();
    viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

            if (b) {
                favouritesArray.integerArray.add(position);

            } else {
                favouritesArray.integerArray.remove(Integer.valueOf(position));
            }
        }
    });

    int songTitle = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
    int songArtist = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);

    String currentTitle = cursor.getString(songTitle);
    String currentArtist = cursor.getString(songArtist);

    viewHolder.title.setText(currentTitle);
    viewHolder.artist.setText(currentArtist);

    //__________________________ALBUM_ART_______________________________________________________

    viewHolder.albumArt.setTag(cursor.getPosition());

    new AsyncTask<ViewHolder, Void, Bitmap>(){

        private ViewHolder viewHolder;

        @Override
        protected Bitmap doInBackground(ViewHolder... viewHolders) {
            viewHolder = viewHolders[0];
            int id = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
            long songId = cursor.getLong(id);

            Bitmap albumArt = getAlbumId(context, songId);
            return albumArt;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if(bitmap != null) {
                viewHolder.albumArt.setImageBitmap(bitmap);
            }else{
                viewHolder.albumArt.setImageResource(R.drawable.placeholder);
            }
        }
    }.execute(viewHolder);
}

private Bitmap getAlbumId(Context context, long id) {

    Bitmap albumArt = null;
    String selection = MediaStore.Audio.Media._ID + " = " + id + "";
    Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{
                    MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM_ID},
            selection, null, null);
    if (cursor.moveToFirst()) {
        long albumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));

        albumArt = getAlbumArt(context, albumId);
    }
    cursor.close();
    return albumArt;

}

private Bitmap getAlbumArt(Context context, long albumId) {

    Bitmap albumArt = null;
    String selection = MediaStore.Audio.Albums._ID + " = " + albumId + "";
    Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null, selection, null, null);

    if (cursor.moveToFirst()) {

        int art = cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);

        String currentArt = cursor.getString(art);
        albumArt = BitmapFactory.decodeFile(currentArt);
    }
    cursor.close();
    return albumArt;
}

}

是的,当然,没有 AsyncTask 一切正常,除了滚动非常慢。 提前致谢!

编辑

归根结底,事情就是这样。非常感谢@Orest Savchak,我赞成并接受你的回答。非常感谢。 //__________________________ALBUM_ART_______________________________________________________

    int id = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
    long songId = cursor.getLong(id);
    String string = getAlbumArtPath(context, songId);
    if(string!=null) {
        Picasso.with(context)
                .load(new File(string))
                .into(viewHolder.albumArt);
    }else{
        viewHolder.albumArt.setImageResource(R.drawable.placeholder);
    }
}
private String getAlbumArtPath(Context context, long id) {

    String selection = MediaStore.Audio.Media._ID + " = " + id + "";
    Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{
                    MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM_ID},
            selection, null, null);
    if (cursor.moveToFirst()) {
        long albumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));

        return getAlbumArt(context, albumId);
    }
    cursor.close();
    return null;

}

private String getAlbumArt(Context context, long albumId) {

    String selection = MediaStore.Audio.Albums._ID + " = " + albumId + "";
    Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null, selection, null, null);

    if (cursor.moveToFirst()) {

        int art = cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);

        return cursor.getString(art);
    }
    cursor.close();
    return null;
}

你应该自己管理你的任务。您的视图被回收,因此,您对不同的行有一个视图,这会导致问题。大多数项目使用一些库,它们会自动为您完成 - 更容易,例如 Picasso

Picasso.with(context).load(new File(getAlbumArtPath(context, songId))).into(viewHolder.albumArt);

private String getAlbumArtPath(Context context, long id) {

    String selection = MediaStore.Audio.Media._ID + " = " + id + "";
    Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{
                    MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM_ID},
            selection, null, null);
    if (cursor.moveToFirst()) {
        long albumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));

        return getAlbumArt(context, albumId);
    }
    cursor.close();
    return null;

}

private String getAlbumArt(Context context, long albumId) {

    String selection = MediaStore.Audio.Albums._ID + " = " + albumId + "";
    Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null, selection, null, null);

    if (cursor.moveToFirst()) {

        int art = cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);

        return cursor.getString(art);
    }
    cursor.close();
    return null;
}