当我使用 AsyncTask 时专辑封面显示不正确 class

Album art is not displaying correct when I use AsyncTask class

当我直接在我的音乐应用程序中显示专辑封面时,它挂起了。在 Whosebug 中,有人建议我实现 AsyncTask。所以,我实现了 AsyncTask 来让我的应用程序更快。现在,我的应用程序没有挂起,但没有显示正确的专辑封面。专辑封面是随机的,这意味着当我滚动列表视图时会经常更改。

请帮帮我。

这是 AsyncTask class :

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private int data = 0;
    private long l;

    public BitmapWorkerTask(ImageView imageView) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    public BitmapWorkerTask(ImageView imageView, long l) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        imageViewReference = new WeakReference<ImageView>(imageView);
        this.l = l;
    }

    // Decode image in background.
    @Override
    protected Bitmap doInBackground(Integer... params) {
        //Bitmap art = getAlbumart(songlist.this, l);
        Context context = songlist.this;
        Bitmap bm = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        try {
            final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
            Uri uri = ContentUris.withAppendedId(sArtworkUri, l);
            ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
            if (pfd != null) {
                FileDescriptor fd = pfd.getFileDescriptor();
                bm = BitmapFactory.decodeFileDescriptor(fd, null, options);
                pfd = null;
                fd = null;
            }
        } catch (Error ee) {
        } catch (Exception e) {
        }
        return bm;
    }

    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            if (bitmap != null) {
                iv_art.setImageBitmap(bitmap);
            } else {
                iv_art.setImageResource(R.mipmap.app_splash_screen_icon);
            }
        }
    }
}

我的 class 在列表视图中显示歌曲 :

public class MediaCursorAdapter extends SimpleCursorAdapter {

    String backgroundColor = "white";
    String someOtherBackgroundColor = "#FAFAFA";

    public MediaCursorAdapter(Context context, int layout, Cursor c) {
        super(context, layout, c,
                new String[]{MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.TITLE, MediaStore.Audio.AudioColumns.DURATION, MediaStore.Audio.Media.ALBUM_ID},
                new int[]{R.id.displayname, R.id.title, R.id.duration, R.id.iv_art});
    }



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


        if (cursor.getPosition() % 2 == 0) {
            view.setBackgroundColor(
                    Color.parseColor(backgroundColor));
        } else {
            view.setBackgroundColor(
                    Color.parseColor(someOtherBackgroundColor));
        }


        TextView title = (TextView) view.findViewById(R.id.title);
        TextView name = (TextView) view.findViewById(R.id.displayname);
        TextView duration = (TextView) view.findViewById(R.id.duration);
        iv_art = (ImageView) view.findViewById(R.id.iv_art);


        String a = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));


        l = Long.parseLong(a);

        bwc = new BitmapWorkerTask(iv_art,l);

        bwc.execute();

        long durationInMs = Long.parseLong(cursor.getString(
                cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION)));

        name.setText(cursor.getString(
                cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)));

        title.setText(cursor.getString(
                cursor.getColumnIndex(MediaStore.MediaColumns.TITLE)));

        Utility d = new Utility();

        String durationInMin = d.convertDuration(durationInMs);

        duration.setText("" + durationInMin);

        view.setTag(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)));
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View v = inflater.inflate(R.layout.songlist_listitem, parent, false);

        bindView(v, context, cursor);

        return v;
    }
}

这是因为行重新排序。当你开始获取时你想要加载它的图像视图不一定是你最后想要加载它的地方。弱引用没有帮助,因为视图没有被破坏,它不再是正确的了。

不是将数据直接加载到视图中,而是将其存储在缓存中,然后调用 notifyDataSetChanged。绑定行时,检查图像是否在缓存中。如果是这样,请使用它。如果没有,请发送请求。这将解决您看到的大部分问题,并防止 OOM 错误(您可以在缓存上设置最大内存使用量)。

或者使用可以为您完成所有这些工作的库,例如 Volley。