ListView与图像非常慢

时间:2014-06-29 11:12:20

标签: java android performance android-listview bitmap

我有一个ListView,其中显示ImageView以向用户显示专辑封面,并显示两个TextView的专辑和艺术家。

但是,当我向上和向下滚动时,它总是非常慢。

public class DSongListAdapter extends ArrayAdapter<Song> {

    Context mContext;
    List<Song> mObjects;

    public DSongListAdapter(Context context, List<Song> songList ) {
        super(context, R.layout.list_item_song, songList );
        this.mContext = context;
        this.mObjects = songList;
    }


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

        ViewHolder holder;
        if( convertView == null ){
            holder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item_song, parent, false);
            holder.titleLabel = (TextView) convertView.findViewById(R.id.titleLabel);
            holder.artistLabel = (TextView) convertView.findViewById(R.id.artistLabel);
            holder.cover = (ImageView) convertView.findViewById(R.id.list_image);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.titleLabel.setText( mObjects.get(position).getTitle() );
        holder.artistLabel.setText( mObjects.get(position).getArtist() );
        Bitmap bm = SongManager.loadBitmap(mContext, mObjects.get(position).getAlbumId() );

        if( bm == null )
            holder.cover.setImageDrawable( mContext.getResources().getDrawable(R.drawable.untitled) );
        else
            holder.cover.setImageBitmap(bm);

        return convertView;
    }

    class ViewHolder {
        TextView titleLabel;
        TextView artistLabel;
        ImageView cover;
    }



}

这是我创建的列表适配器。 SongManager.loadBitmap()方法返回位图或null。如果它为null,我将使用我的资源中的默认位图。

我可以做些什么来提高速度?例如亚马逊音乐播放器比我的更快更流畅!另外我注意到我的应用需要42 MB的Ram。这太过分了吗?

修改

public static Bitmap loadBitmap( Context c, int album_id ){
    Bitmap bm = null;
    try {
        final Uri sArtworkUri = Uri
                .parse("content://media/external/audio/albumart");

        Uri uri = ContentUris.withAppendedId(sArtworkUri,
                album_id);

        ParcelFileDescriptor pfd = c.getContentResolver()
                .openFileDescriptor(uri, "r");

        if (pfd != null) {
            FileDescriptor fd = pfd.getFileDescriptor();
            bm = BitmapFactory.decodeFileDescriptor(fd);
        }
    } catch (Exception e) {

    }

    return bm;
}

2 个答案:

答案 0 :(得分:2)

您正在每getView()次呼叫执行IPC和间接磁盘I / O.如果你使用Traceview,你会认为这是你困难的根源。

请考虑使用像Picasso这样的库来异步加载这些图像并缓存它们。还有许多其他类似的库 - 请参阅&#34;图像加载器&#34;和&#34;图像视图&#34; the Android Arsenal中的类别。

答案 1 :(得分:0)

你永远不应该对ui线程进行I / O操作。而不是这个,你应该异步加载你的图像。幸运的是,有一个良好的图书馆的基调这样做。看看这个,它很容易使用和自定义:https://github.com/nostra13/Android-Universal-Image-Loader