Anonymous
ListView — исключение outOfMemory
Сообщение
Anonymous » 14 фев 2026, 00:48
Я создаю пользовательский интерфейс в стиле Pulse. Для этого я использую Gallery внутри ListView. Однако я столкнулся со странной проблемой: выделение памяти в моем приложении постепенно увеличивается с 9 МБ до 64 МБ при прокрутке списка, пока оно, наконец, не выходит из строя.
Что не сработало:
Я сомневался, что это из-за растровых изображений, которые я использую. Итак, я протестировал его без изображений внутри галереи. Я также использовал библиотеку Universal Image Loader. Однако ничего не изменилось.
Я читал аналогичный вопрос в SO, что отключение прокруткиCache в listView может помочь. Однако эффекта по-прежнему нет.
Что сработало:
Разработка эффективного адаптера с использованием ViewHolder, getTag(), setTag() решила проблемы с памятью. Однако возникла странная проблема: listView иногда отображает пустые или повторяющиеся строки, тем самым отображая неправильные данные в пользовательском интерфейсе. Как я могу это решить? Есть ли лучший подход для этого?
ListViewAdapter.java
Код: Выделить всё
public class ListViewAdapter extends BaseAdapter {
String user_locale;
Context context;
LayoutInflater inflater;
AssetsAdapter assestsAdapter;
List categoryList;
List baseAssetList;
AssetsTable assetTable;
ViewHolder viewHolder;
public ListViewAdapter(Context context, List 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 baseAssetsList;
Gallery.LayoutParams params;
public GalleryAdapter(Context context, List 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;
}
Подробнее здесь:
https://stackoverflow.com/questions/160 ... -exception
1771019287
Anonymous
Я создаю пользовательский интерфейс в стиле Pulse. Для этого я использую Gallery внутри ListView. Однако я столкнулся со странной проблемой: выделение памяти в моем приложении постепенно увеличивается с 9 МБ до 64 МБ при прокрутке списка, пока оно, наконец, не выходит из строя. [b]Что не сработало:[/b] [list] [*]Я сомневался, что это из-за растровых изображений, которые я использую. Итак, я протестировал его без изображений внутри галереи. Я также использовал библиотеку Universal Image Loader. Однако ничего не изменилось. [*]Я читал аналогичный вопрос в SO, что отключение прокруткиCache в listView может помочь. Однако эффекта по-прежнему нет. [/list] [b]Что сработало:[/b] [list] [*]Разработка эффективного адаптера с использованием ViewHolder, getTag(), setTag() решила проблемы с памятью. Однако возникла странная проблема: listView иногда отображает пустые или повторяющиеся строки, тем самым отображая неправильные данные в пользовательском интерфейсе. Как я могу это решить? Есть ли лучший подход для этого? [/list] [b]ListViewAdapter.java[/b] [code]public class ListViewAdapter extends BaseAdapter { String user_locale; Context context; LayoutInflater inflater; AssetsAdapter assestsAdapter; List categoryList; List baseAssetList; AssetsTable assetTable; ViewHolder viewHolder; public ListViewAdapter(Context context, List 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; } [/code] [b]GalleryAdapter.java:[/b] [code]public class GalleryAdapter extends BaseAdapter { final String TAG_PORTRAIT = "portrait"; LayoutInflater inflater; ImageLoader imageLoader; DisplayImageOptions options; Context context; List baseAssetsList; Gallery.LayoutParams params; public GalleryAdapter(Context context, List 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; } [/code] Подробнее здесь: [url]https://stackoverflow.com/questions/16029494/listview-outofmemory-exception[/url]