ListView滞后于音乐专辑图片

我正在构建一个音乐播放器,它应该有一个listView,其中包含title-artistname和albumcover的图像。 这似乎变得非常迟钝。 如何提高性能?

我获取这些图片的function是这样的:

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

编辑: 在此处输入图像描述

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

android.provider.MediaStore.Audio.AlbumColumns.ALBUM_ART

使用我的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 { private final WeakReference imageViewReference; private String path; public BitmapWorkerTask(ImageView imageView) { // Use a WeakReference to ensure the ImageView can be garbage collected imageViewReference = new WeakReference(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 bitmapWorkerTaskReference; public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { super(res, bitmap); bitmapWorkerTaskReference = new WeakReference(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; } } 

要使用它,请在Adapter创建AlbumArtLoader实例

 AlbumArtLoader mArtLoader; 

使用实例化它

 mArtLoader = new AlbumArtLoader(context); 

在您的Adapter构造函数中,它从您的Activity接收Context

然后在getView()

 mArtLoader.loadBitmap(pathToAlbumArt, vh.imgAlbumart); 

额外:从光标获取专辑封面路径

 int artColumnIndex = albumCursor.getColumnIndex(MediaStore.Audio.AlbumColumns.ALBUM_ART); if(albumCursor!=null && albumCursor.moveToFirst()) { do { String artPath = albumCursor.getString(artColumnIndex); } while (albumCursor.moveToNext()); } 

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

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