2013-05-22 5 views
2

Whats up люди.BitmapFactory OutOfMemory

Я пытаюсь сделать каталог продукции, и это то, что я делаю:

  • активность с ViewPager - Каждый продукт представляет собой фрагмент в этом ViewPager. - У каждого фрагмента есть Галерея.

Загружайте данные и изображения продуктов из Интернета и храните их в SD-карте.

Но мое приложение держать сбой, и это ошибка

05-22 10:04:43.829: E/AndroidRuntime(12388): FATAL EXCEPTION: main 
05-22 10:04:43.829: E/AndroidRuntime(12388): java.lang.OutOfMemoryError 
05-22 10:04:43.829: E/AndroidRuntime(12388): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
05-22 10:04:43.829: E/AndroidRuntime(12388): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493) 
05-22 10:04:43.829: E/AndroidRuntime(12388): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299) 
05-22 10:04:43.829: E/AndroidRuntime(12388): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:324) 

Я использовал де растровый завод внутри GetView на адаптере галереи, но он выходит из строя, когда я красть фрагменты. Затем я изменил и создал и List, когда была создана основная активность, но теперь, если я закрою действие и попытаюсь открыть его снова, он сработает, ТОГДА, если я попытаюсь открыть его снова, он откроется нормально.

Что я делаю неправильно? Есть лучший способ сделать это?

это мой адаптер Галерея

public class ImagemAdapter extends BaseAdapter { 

     private Context ctx; 
     List<Bitmap> pics; 

     public ImagemAdapter(Context c, List<Bitmap> pics) { 
      ctx = c; 
      this.pics = pics; 
     } 

     @Override 
     public int getCount() { 

      return pics.size(); 
     } 

     @Override 
     public Object getItem(int position) { 
      return pics.get(position); 
     } 

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

     @Override 
     public View getView(int position, View convertView, ViewGroup parent){ 
      if(convertView == null){ 
       int arquivoLayout = R.layout.adp_galeria; 
       LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       convertView = inflater.inflate(arquivoLayout, null); 
       ImageView img = ((ImageView)convertView.findViewById(R.id.imgProd));    
       img.setImageBitmap(pics.get(position)); 
      } 
      return convertView; 
     } 

} 

другая странная вещь есть, convertView на адаптере ВСЕГДА нуль.

EDIT:

Я думаю, что проблема в том, что точечный рисунок сохраняет в памяти. Когда onCreateView фрагмента называется, я заполнить список с изображениями я должен показать и когда onDestroyView фрагмента называется, я делаю это:

for(int i =0; i< imagemBit.size(); i++){ 
    Bitmap bmp = imagemBit.get(i); 
    bmp.recycle(); 
    bmp = null; 
} 
imagemBit.clear(); 

НО: Когда onCreateView вызывается еще раз (пользователь возвращается на предыдущую страницу), когда я пытаюсь снова заполнить список, из которого приложение вылетает с OutOfMemory Exception.

+0

использовать держатель для представления и гладкой прокрутки. Если изображение слишком велико, уменьшите то же самое значение – Raghunandan

+0

, как использовать держатель вида, если преобразованиеView всегда равно нулю? – JannGabriel

+0

http://developer.android.com/training/improving-layouts/smooth-scrolling.html – Raghunandan

ответ

2

Пожалуйста, посмотрите на this answer
я испытал те же проблемы по загрузке и показывая множество изображений с кэшированием в памяти. Убедитесь, что в памяти осталось не больше некоторого количества изображений (в зависимости от размера).

+0

как мне освободить изображение из памяти? – JannGabriel

+0

Поскольку память для декодирования растровых изображений выделяется изначально вместо выделения в кучу, для GC ее более сложно освободить. К счастью, у Bitmap есть метод recycle(), который мгновенно освобождает память. – ooops

+0

Я использую recycle() внутри цикла for, чтобы освободить каждый из них в списке, и я использую list.clear(). Но все еще имея исключение OutOfMemory – JannGabriel

1

Где ваше приложение падает на ваш код?

Я думаю, что после того, как вы закроете свое приложение, «pics» все еще сохраняет ссылку на растровые изображения, и поэтому GC не выпускает растровые изображения. Вы должны выпустить растровые изображения, когда ваше приложение останавливается или перед созданием новых растровых изображений.

+0

это правильно. он сохраняет ссылку, потому что он падает при попытке загрузить bitmapfactory снова. Я попытался добавить много фотографий, и он ВСЕГДА падает. Я думаю, что другая проблема связана с размером изображений. Вы знаете, как обрабатывать большое количество больших изображений? – JannGabriel

+0

Вы должны использовать загрузчик изображений, который работает в backgroud.Если ваши изображения из сети вы можете использовать андроидный запрос: https://code.google.com/p/android-query/downloads/detail?name=android-query-full.0.24.3.jar. читайте здесь https://code.google.com/p/android-query/#Image_Loading. если нет, возможно, эта библиотека может вам помочь. если нет, то я рекомендую следующее: использовать массив растровых изображений, массив деталей растровых изображений. при запуске перезагрузите их, если они не равны нулю. Используйте AsyncTask для создания растровых изображений по вашим растровым изображениям. – Alex248

+0

man, я использую и массивы растровых изображений создаю внутри onCreateView фрагмента и уничтожаю его наDestroyView. Он вылетает перед открытием приложения. Что я делаю не так? – JannGabriel