【问题标题】:Album art is not displaying correct when I use AsyncTask class当我使用 AsyncTask 类时,专辑封面显示不正确
【发布时间】:2017-06-12 07:14:49
【问题描述】:

当我直接在我的音乐应用中显示专辑封面时,它会挂起。在 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;
    }
}

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 缓存位图不能解决这个问题@Gabe
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多