ListView落后于音乐专辑图片

时间:2015-09-02 11:20:42

标签: java android listview

我正在制作一个音乐播放器,它应该有一个带有title-artistname的listView和albumcover的图像。这似乎变得非常迟钝。如何提高绩效?

我获取这些照片的功能是这样的:

public static Bitmap getAlbumart(Context context,Long album_id){
  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, album_id);
    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){bm = BitmapFactory.decodeResource(context.getResources(),R.drawable.cd_128x128); }
catch (Exception e) { bm = BitmapFactory.decodeResource(context.getResources(),R.drawable.cd_128x128);}
return bm;}

如果我每次都在我的getView函数中执行此操作,应用程序将自行终止。所以我试图先将它们保存在位图的Arraylist中,但这需要太长时间。我已经尝试使用Viewholder,但这确实不会影响性能。

我的getview看起来像这样

`@Override
    public View getView(int position, View view, ViewGroup parent) {

        View rview = view;
        holder = null;


        if (rview == null)
        {
            LayoutInflater inflater = context.getLayoutInflater();
            rview= inflater.inflate(R.layout.row_song, null, true);
            holder = new ViewHolder(rview);
            rview.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) rview.getTag();
        }


        holder.imgAlbumart.setImageBitmap(Music.getAlbumart(context, Long.valueOf(AL_songlist.get(position).getAlbumID())));

        holder.txtTitle.setText(AL_songlist.get(position).getTitle());
        holder.txtArtist.setText(AL_songlist.get(position).getArtist());


        return rview;
        }`

编辑:enter image description here

当我尝试时,它是一样的。

  

android.provider.MediaStore.Audio.AlbumColumns.ALBUM_ART

2 个答案:

答案 0 :(得分:2)

使用我的AlbumArtLoader.java。我是从Android开发者网站获得的,但无法找到该页面。我修改它使它比提供的代码更顺畅。

/* Loads images smoothly in ListView */


public class AlbumArtLoader {
    private Context ctx;
    private int artSize;
    private final Bitmap mPlaceHolderBitmap;
    private Drawable[] drawables = new Drawable[2];
    public AlbumArtLoader(Context c) {
        ctx = c;
        artSize = c.getResources().getDimensionPixelSize(R.dimen.albumart_size);
        mPlaceHolderBitmap = BitmapFactory.decodeResource(ctx.getResources(), R.drawable.transparent);
        mPlaceHolderBitmap = Bitmap.createScaledBitmap(mPlaceHolderBitmap, artSize, artSize, false);
        drawables[0] = new BitmapDrawable(ctx.getResources(), mPlaceHolderBitmap);
    }
    class BitmapWorkerTask extends AsyncTask<String, Void, TransitionDrawable> {
        private final WeakReference<ImageView> imageViewReference;
        private String path;
        public BitmapWorkerTask(ImageView imageView) {
            // Use a WeakReference to ensure the ImageView can be garbage collected
            imageViewReference = new WeakReference<ImageView>(imageView);
        }
        // Decode image in background.
        @Override
        protected TransitionDrawable doInBackground(String... params) {
            path = params[0];
            // TransitionDrawable let you to make a crossfade animation between 2 drawables
            // It increase the sensation of smoothness
            TransitionDrawable td = null;

            // The albumart_unknown bitmap is recreated for each album without album art to maintain even scrolling
            if(path == null) {
                Bitmap b = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(ctx.getResources(), R.drawable.albumart_unknown), artSize, artSize, true);
                drawables[1] = new BitmapDrawable(ctx.getResources(), b);
            } else {
                Bitmap b;
                try {
                    b = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(path), artSize, artSize, true);
                } catch(Exception e) {
                    b = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(ctx.getResources(), R.drawable.albumart_unknown), artSize, artSize, true);
                }
                drawables[1] = new BitmapDrawable(ctx.getResources(), b);
            }
            td = new TransitionDrawable(drawables);
            td.setCrossFadeEnabled(true);
             return td;
        }
        // Once complete, see if ImageView is still around and set bitmap.
        @Override
        protected void onPostExecute(TransitionDrawable td) {
            if(isCancelled()) {
                td = null;
            }
            if(imageViewReference != null && td != null) {
                final ImageView imageView = imageViewReference.get();
                final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
                if(this == bitmapWorkerTask && imageView != null) {
                    imageView.setImageDrawable(td);
                    td.startTransition(200);
                }
            }
        }
    }

    public void loadBitmap(String path, ImageView imageView) {
        if(cancelPotentialWork(path, imageView)) {
            final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
            final AsyncDrawable asyncDrawable = new AsyncDrawable(ctx.getResources(), mPlaceHolderBitmap, task);
            imageView.setImageDrawable(asyncDrawable);
            task.execute(path);
        }
    }

    static class AsyncDrawable extends BitmapDrawable {
        private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
        public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
            super(res, bitmap);
            bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
        }
        public BitmapWorkerTask getBitmapWorkerTask() {
            return bitmapWorkerTaskReference.get();
        }
    }

    public static boolean cancelPotentialWork(String path, ImageView imageView) {
        final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
        if(bitmapWorkerTask != null) {
            final String bitmapData = bitmapWorkerTask.path;
            // If bitmapData is not yet set or it differs from the new data
            if(bitmapData == null || bitmapData != path) {
                // Cancel previous task
                bitmapWorkerTask.cancel(true);
            } else {
        // The same work is already in progress
                return false;
            }
        }
        // No task associated with the ImageView, or an existing task was cancelled
        return true;
    }

    // Helper method
    private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
        if(imageView != null) {
            final Drawable drawable = imageView.getDrawable();
            if(drawable instanceof AsyncDrawable) {
                final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
                return asyncDrawable.getBitmapWorkerTask();
            }
        }
        return null;
    }
}

要使用它,请在AlbumArtLoader

中创建Adapter个实例
AlbumArtLoader mArtLoader;

使用

实例化它
mArtLoader = new AlbumArtLoader(context);

Adapter构造函数中,该构造函数从Context接收Activity

然后在getView()

mArtLoader.loadBitmap(pathToAlbumArt, vh.imgAlbumart);

EXTRA:从光标获取专辑封面艺术路径

int artColumnIndex = albumCursor.getColumnIndex(MediaStore.Audio.AlbumColumns.ALBUM_ART);

if(albumCursor!=null && albumCursor.moveToFirst()) {
    do {
        String artPath = albumCursor.getString(artColumnIndex);
    }  while (albumCursor.moveToNext());
}

答案 1 :(得分:0)

您可以使用AQuery进行异步图像加载:

https://code.google.com/p/android-query/wiki/AsyncAPI