Я создаю средство просмотра книг для Android 3.0 Honeycomb. Он отлично работает на Samsung Galaxy Tab, но получает множество ошибок OutOfMemory на Motorola Xoom на 3.0.1. Оба устройства имеют пространство кучи виртуальной машины 48 МБ.
У меня есть 2 занятия:
BookActivity
- имеет SlowGallery
, который загружает изображения 1280x640, и небольшую галерею, которая загружает изображения 160x80.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * '' * '* * * * * * *' '*' * * * * * * * * * * «Мозг» - это незначительное переопределение.
BitmapActivity
- имеет один ImageView
, который загружает изображение 4488x2244, и небольшую галерею, которая загружает изображения 160x80. Уменьшение размера изображения не вариант, поскольку пользователь намерен увеличить изображение до 100%.
Я поместил это в метод загрузки растровых изображений, чтобы уменьшить растровое изображение до 16-разрядных:
BitmapFactory.Options o2 = new BitmapFactory.Options();
if (compressColor) o2.inPreferredConfig = Bitmap.Config.RGB_565;
o2.inPurgeable = true;
o2.inInputShareable = true;
o2.inSampleSize = (int) scale;
b = BitmapFactory.decodeStream(fis, null, o2);
Когда я дважды щелкаю по галерее BookActivity, она вызывает BitmapActivity, передавая соответствующий номер изображения, который нужно открыть. Я могу сделать это 1-3 раза, введя BitmapActivity, затем щелкнув Назад, прежде чем он попадет в OutOfMemoryError.
При двойном прикосновении к Галерее вызывается PageAdapter.purge (), который, по-видимому, визуально выгружает изображения галереи.
Это BookActivity.PageAdapter, который является адаптером для SlowGallery:
private class PageAdapter extends BaseAdapter {
private final LayoutInflater mInflater;
private Page currentPage;
private boolean purge = false;
private WeakReference<Bitmap> weakReferenceBitmap;
public PageAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public void unpurge() {
purge = false;
notifyDataSetChanged();
}
public void purge() {
purge = true;
holder = null;
notifyDataSetChanged();
}
@Override
public int getCount() {
if (listPages==null || purge) return 0;
return listPages.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.gallery_pages, null);
holder = new ViewHolderIssues();
holder.image = (ImageView) convertView.findViewById(R.id.ImageViewPage);
convertView.setTag(holder);
} else {
holder = (ViewHolderIssues) convertView.getTag();
}
if (position < listPages.size()) {
currentPage = listPages.get(position);
File f = new File(Engine.PATH + currentPage.getImageMedium());
if (!purge) {
if (!f.exists()) {
holder.image.setImageResource(R.drawable.loading);
Engine.triggerTrickle(currentPage.getImageMedium(), WeightedAsset.IMAGE_MEDIUM, getApplicationContext());
} else {
weakReferenceBitmap = new WeakReference<Bitmap>(Engine.loadImageFromBitmap(currentPage.getImageMedium(), screenWidth, 1, true));
if (weakReferenceBitmap.get()!=null) {
holder.image.setImageBitmap(weakReferenceBitmap.get());
} else {
holder.image.setImageDrawable(null);
}
}
} else {
weakReferenceBitmap.clear();
holder.image.setImageDrawable(null);
holder = null;
System.gc();
}
f = null;
}
return convertView;
}
}
Глядя на файл HPROF, под деревом доминатора, кажется, что BookActivity.SlowGallery
все еще существует, даже когда я нахожусь в BitmapActivity
. Когда в BookActivity
, SlowGallery
занимает 3,2-6,5 МБ (1,6 МБ на изображение), но в BitmapActivity
это занимает 1,6 МБ (SlowGallery.LinearLayout.ImageView.BitmapDrawable
= 1,6 МБ). Как мне избавиться от SlowGallery
?