使用AsyncTask类时,专辑封面显示不正确

时间:2017-01-26 17:54:16

标签: android performance android-studio android-asynctask android-cursor

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

请帮帮我。

这是AsyncTask类:

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);
            }
        }
    }
}

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

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;
    }
}

1 个答案:

答案 0 :(得分:1)

因为行重新排序。在开始提取时要将其加载到的图像视图不一定是您要在最后加载它的位置。弱参考没有帮助,因为视图没有被破坏,它不再是正确的。

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

或者使用一个能够为你完成所有这些工作的库,比如Volley。