ListView - outOfMemory异常

时间:2013-04-16 05:35:30

标签: android listview gallery pulse

我正在构建一种Pulse类型的UI。为此我在Gallery内使用ListView。但是,我面临一个奇怪的问题,当我滚动浏览listview时,我的应用程序中的内存分配从9 MB逐渐增加到64 MB,直到最终崩溃。

什么行不通:

  • 我怀疑这是因为我正在使用的位图。所以,我测试了没有图库内的图像。我还使用了Universal Image Loader库。然而,没有任何改变。

  • 我在SO中读到了类似的问题,禁用listView的scrollingCache可能有所帮助。但是,仍然没有效果。

什么有效:

  • 使用ViewHolder设计高效的适配器,getTag()setTag()解决了内存问题。但是,它带来了一个奇怪的问题,listView有时会显示空行或重复行,从而在UI中显示错误的数据。我怎么解决这个问题?有没有更好的方法来解决这个问题?

ListViewAdapter.java

public class ListViewAdapter extends BaseAdapter {
    String user_locale;
    Context context;
    LayoutInflater inflater;
    AssetsAdapter assestsAdapter;
    List<Category> categoryList;
    List<BaseAssets> baseAssetList;
    AssetsTable assetTable;
    ViewHolder viewHolder;

public ListViewAdapter(Context context, List<Category> categoryList) {
    this.context = context;
    user_locale = Universal.getCurrentLanguage(context);
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.categoryList = categoryList;
    assetTable = new AssetsTable(context);
    viewHolder = new ViewHolder();
}

public int getCount() {
    return categoryList.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

public View getView(final int position, View convertView, ViewGroup parent) {
    String catID = categoryList.get(position).catID;

    if (convertView == null)
    {
        convertView = inflater.inflate(R.layout.category_list_item, parent, false);
        viewHolder.categoryTitle = (TextView) convertView.findViewById(R.id.category_title);
        viewHolder.gallery = (Gallery) convertView.findViewById(R.id.gallery);
        convertView.setTag(viewHolder);
    } else
        viewHolder = (ViewHolder) convertView.getTag();

    assetTable = new AssetsTable(context);
    int count = assetTable.getCountOfParticularCategory(catID);

    initializeGallery(catID);

    String text = categoryList.get(position).catName + "  (" + count + ")  ";
    viewHolder.categoryTitle.setText(text);
    return convertView;

}

public void initializeGallery(String catID) {
    assetTable = new AssetsTable(context);
    baseAssetList = assetTable.getAllBaseAssets(catID);
    assestsAdapter = new AssetsAdapter(context, baseAssetList);
    adjustGalleryHeight();
    viewHolder.gallery.setAdapter(assestsAdapter);
}

public void adjustGalleryHeight() {
    boolean isPortrait = false;
    final String TAG_PORTRAIT = "portrait";

    for (BaseAssets b : baseAssetList)
    {
        if (b.thumbOrientation.equals(TAG_PORTRAIT))
            isPortrait = true;
    }

    final float scale = context.getResources().getDisplayMetrics().density;
    if (isPortrait)
    {
        RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) viewHolder.gallery.getLayoutParams();
        params1.height = (int) (350 * scale);
        viewHolder.gallery.setLayoutParams(params1);
    } else
    {
        RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) viewHolder.gallery.getLayoutParams();
        params1.height = (int) (280 * scale);
        viewHolder.gallery.setLayoutParams(params1);
    }
}

class ViewHolder {
    TextView categoryTitle;
    Gallery gallery;

}

}

GalleryAdapter.java:

public class GalleryAdapter extends BaseAdapter {

final String TAG_PORTRAIT = "portrait";
LayoutInflater inflater;
ImageLoader imageLoader;
DisplayImageOptions options;
Context context;
List<BaseAssets> baseAssetsList;

Gallery.LayoutParams params;

public GalleryAdapter(Context context, List<BaseAssets> baseAssetsList) {
    imageLoader = ImageLoader.getInstance();
    options = new DisplayImageOptions.Builder().cacheOnDisc().imageScaleType(ImageScaleType.EXACTLY).bitmapConfig(Bitmap.Config.RGB_565).cacheInMemory().showStubImage(
            R.drawable.no_preview).build();
    this.context = context;
    this.baseAssetsList = baseAssetsList;
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

public int getCount() {
    return baseAssetsList.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

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

    ViewHolder viewHolder;
    if (convertView == null)
    {
        viewHolder = new ViewHolder();
        convertView = inflater.inflate(R.layout.gallery_list_item, parent, false);
        viewHolder.galleryWrapper = (RelativeLayout) convertView.findViewById(R.id.gallery_wrapper);
        viewHolder.downloadThumbnail = (ImageView) convertView.findViewById(R.id.thumbnailDownloadStatus);
        viewHolder.assetImage = (ImageView) convertView.findViewById(R.id.thumbnail_image);
        viewHolder.assetName = (TextView) convertView.findViewById(R.id.thumbnail_name);
        convertView.setTag(viewHolder);
    } else
        viewHolder = (ViewHolder) convertView.getTag();

    final float scale = context.getResources().getDisplayMetrics().density;

    if (baseAssetsList.get(position).thumbOrientation.equals(TAG_PORTRAIT))
    {

        params = new Gallery.LayoutParams((int) (166 * scale), (int) (245 * scale));
        viewHolder.galleryWrapper.setLayoutParams(params);

    } else
    {
        params = new Gallery.LayoutParams((int) (238 * scale), (int) (191 * scale));
        viewHolder.galleryWrapper.setLayoutParams(params);
    }

    viewHolder.assetName.setText(baseAssetsList.get(position).contentTitle);
    String raw_url = baseAssetsList.get(position).thumbnail;
    String correctUrl = correctUrl(raw_url);
    imageLoader.displayImage(correctUrl, viewHolder.assetImage, options);

    convertView.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            Intent intent = new Intent(context, DownloadActivity.class);
            intent.putExtra(Universal.ASSET_TYPE, baseAssetsList.get(position).contentType);
            intent.putExtra(Universal.ASSET_TITLE, baseAssetsList.get(position).contentTitle);
            intent.putExtra(Universal.ASSET_URL, baseAssetsList.get(position).path);
            intent.putExtra(Universal.ASSET_LARGE_THUMBNAIL, baseAssetsList.get(position).thumbnail);

            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            context.startActivity(intent);

        }
    });

    return convertView;
}

public String correctUrl(String raw_url) {
    String corrected_url = raw_url;
    if (!raw_url.contains("http:/"))
        corrected_url = ("http:/" + raw_url);
    return corrected_url;
}

class ViewHolder {
    RelativeLayout galleryWrapper;
    ImageView assetImage;
    ImageView downloadThumbnail;
    TextView assetName;

}

}

2 个答案:

答案 0 :(得分:2)

ListViewAdapter你没有打电话

viewHolder = new ViewHolder();
getView()convertView时,null中的

检查一下!这可能是问题所在。

答案 1 :(得分:1)

尝试更改“viewHolder = new ViewHolder();”如果convertview为null,则在适配器的getview内;

喜欢:

public View getView(final int position, View convertView, ViewGroup parent) {
String catID = categoryList.get(position).catID;

if (convertView == null)
{
    viewHolder = new ViewHolder(); //Add this line. Otherwise u are sharing the same instance for other views.
    convertView = inflater.inflate(R.layout.category_list_item, parent, false);
    viewHolder.categoryTitle = (TextView) convertView.findViewById(R.id.category_title);
    viewHolder.gallery = (Gallery) convertView.findViewById(R.id.gallery);
    convertView.setTag(viewHolder);
} else
    viewHolder = (ViewHolder) convertView.getTag();

assetTable = new AssetsTable(context);
int count = assetTable.getCountOfParticularCategory(catID);

initializeGallery(catID);

String text = categoryList.get(position).catName + "  (" + count + ")  ";
viewHolder.categoryTitle.setText(text);
return convertView;

}