2014-02-21 3 views
1

Будет немного легче понять это, если вы думаете, что приложение, над которым я работаю, как facebook (по крайней мере, это даст вам контекст для того, что я делаю). У меня есть одно действие, которое использует навигатор для обмена фрагментами, каждый из этих фрагментов может иметь от одного до нескольких «субфрагментов». Думайте об этом как о отдельных сообщениях с такими вещами, как textview, несколько кнопок и ImageView. Когда создается «фрагмент контейнера», я вызываю сервер и получаю данные, необходимые для создания всех «фрагментов». Затем я перебираю данные и добавляю все «донные фрагменты» в представление «фрагмент контейнера».Ошибки Android OOM из-за кэширования изображений?

Я заметил, что я использую чрезмерно большой объем памяти (около 129 мб).

Когда создаются подфрагменты, я вызываю эту задачу async, которая извлекает изображения, необходимые каждому фрагменту с сервера, и помещает их в свой ImageView.

public class URLImageFactory extends AsyncTask<String, Void, Bitmap> 
{ 
    ImageView imgView; 
    private static final ImgCache mCache = new ImgCache(); 

    public URLImageFactory(ImageView bmImage) { 
     this.imgView = bmImage; 
    } 

    @Override 
    protected Bitmap doInBackground(String... urls) { 
     String urldisplay = Config.SERVER_URL + urls[0].replaceAll("\\s+","%20"); 

     Bitmap bitmap = null; 
     //If it is in the cache don't bother pulling it from the server 
     if(bitmap != null) 
     { 
      return bitmap; 
     } 

     try { 
      InputStream in = new java.net.URL(urldisplay).openStream(); 
      //This is in case we are using match_parent/wrap content 
      if(imgView.getWidth() == 0 || imgView.getHeight() == 0) 
      { 
       bitmap = BitmapFactory.decodeStream(in); 
      } else { 
       bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(in), 
         imgView.getWidth(), imgView.getHeight(), false); 
      } 
      mCache.put(urldisplay,bitmap); 
     } catch (Exception e) { 
      Log.e("Error", e.getMessage()); 
      e.printStackTrace(); 
     } 
     return bitmap; 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) { 
     imgView.setImageBitmap(result); 
    } 
} 

Я сделал элементарную попытку кэширования изображений ускорить процесс

общественного класса ImgCache расширяет LruCache {

public ImgCache() { 
     super(calculateCacheSize()); 
    } 

    public static int calculateCacheSize() 
    { 
     int maxMemory = (int) Runtime.getRuntime().maxMemory()/8; 
     int cacheSize = maxMemory; 
     return cacheSize; 
    } 

    @Override 
    protected int sizeOf(String key, Bitmap value) { 
     return value.getByteCount()/1024; 
    } 
} 

Мое приложение рушится с OutOfMemory исключением. Я также заметил, что когда мой «фрагмент контейнера» заменяется на другой ... обычно аналогично структурированный фрагмент ... onPause() и onStop() этих подфрагментов не запускаются. Если это помогает, то субфрагменты являются статическими внутренними классами, а фрагмент контейнера - нет. Я думаю, что это проблема, связанная с растровым изображением, но я не уверен. Я попытался использовать TransactionManager.remove (фрагмент) во всех дочерних фрагментах, когда родительский элемент попадает в onPause, но он, похоже, не помогает.

+0

Вы пытались использовать анализатор памяти eclipse, чтобы узнать, какие объекты занимают память в вашем приложении? Кроме того, нужно указать «Runtime.getRuntime(). MaxMemory()' сообщает вам количество байтов. Почему вы разделите его на 8? –

+0

Я разделил его на 8, потому что я понял, что 1/8-я память была подходящей для кеша ... было больше угадывания – ed209

+0

Я не мог не заметить, что каждый раз, когда он добавляет растровое изображение в пользовательский интерфейс, он выплевывается. Grow heap (фрагмент case) до #### – ed209

ответ

2

Вы делите количество байтов каждого объекта на 1024, но только разделите доступную память на 8; результатом является то, что кеш LRU может заполнить до 128 раз больше доступной памяти. Удалите / 1024 от sizeOf, и вы должны быть хорошими.

Смежные вопросы