我正在制作一个音乐播放器,它应该有一个带有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;
}`
当我尝试时,它是一样的。
android.provider.MediaStore.Audio.AlbumColumns.ALBUM_ART
答案 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进行异步图像加载: