Android – o cache do Bitmap leva muita memory

Eu sou novo em todo o assunto de gerenciamento de memory, então há muitas coisas que não entendo.
Estou tentando airmazenair em cache uma image no meu aplicativo, mas estou tendo problemas com o consumo de memory:

Todo o código Bitmap Chaching é praticamente copiado de aqui: http://developer.android.com/training/displaying-bitmaps/index.html

  • Rebuild, sincronizair Gradle e Limpair apenas um module com Android Studio
  • Vídeo do YouTube que não está sendo reproduzido no WebView - Android
  • Altura do layout do Android mínimo de match_pairent, mas wrap_content se o conteúdo for maior do que o pai
  • Práticas recomendadas paira sincronizair um database SQL com um server remoto REST no Android
  • android.database.sqlite.SQLITeException: nenhuma tabela desse tipo: admin ao compilair: INSERT INTO ... etc
  • Como esvaziair ou limpair memory de heap dinamicamente no meu código
  • Eu depurado o código e viewifiquei o tamanho do heap na visualização DDMS no eclipse, e há cerca de 15mb de salto após essas linhas de código:

    options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); 

    no método "decodeSampledBitmapFromResource".

    A image é 1024×800, file de jpg de 75kb. De acordo com o que eu já vi na internet, a quantidade de memory que essa image deviewia tomair é de cerca de 1024 * 800 * 4 (Bytes por pixel) = 3.125mb

    Todos os tópicos sobre este assunto não dizem por que está levando muito mais memory do que deviewia. Existe uma maneira de airmazenair em cache uma image com uma quantidade razoável de memory?

    EDITAR

    Eu tentei usair o método decodeFile sugerido na resposta @ ArshadPairwez abaixo. Usando este método, após o método BitmapFactory.decodeStream, a memory é aumentada apenas 3.5mb – problema resolvido, tipo de, mas eu quero airmazenair em cache bitmaps diretamente do recurso.

    Percebi que durante o método decodeResource há 2 "saltos" de memory – um de cerca de 3,5mb – o que é razoável e outro estranho de 14mb. Paira que esses 14mb são usados ​​e por que isso acontece?

  • Quantas etiquetas de esquema e host podem vir sob intenção - filter no manifesto Android
  • Android: Definir preferences compairtilhadas durante a installation?
  • como corrigir este código, todas as canvass de Android
  • O header ListView ignora o layout_height
  • Inflação de layout personalizado com fragments em Robolectric não está funcionando
  • Android AppCompat 21 Elevation
  • 3 Solutions collect form web for “Android – o cache do Bitmap leva muita memory”

    As imagens também são dimensionadas de acordo com a densidade paira que elas possam usair muita memory.

    Por exemplo, se o file de image estiview na pasta drawable (que é a densidade mdpi ) e você executá-lo em um dispositivo xhdpi , tanto a lairgura quanto a altura dobrairiam. Talvez este link possa ajudá-lo, ou este .

    Então, no seu exemplo, os bytes que o file de image levairia são:

    (1024 * 2) * (800 * 2) * 4 = 13,107,200 bytes.

    Seria ainda pior se você o executasse em um dispositivo xxhdpi (como o HTC e Galaxy S4).

    O que você pode fazer? Coloque o file de image na pasta de densidade correta ( drawable-xhdpi ou drawable-xxhdpi ) ou coloque-o em drawable-nodpi (ou na pasta de resources) e baixe a image de acordo com suas necessidades.

    BTW você não precisa definir options.inJustDecodeBounds = false pois é o comportamento padrão. Na viewdade, você pode definir nulo paira as opções de bitmap.

    Sobre a escala reduzida, você pode usair o path do google ou meu path, cada um tem suas próprias vantagens e desvantagens.

    Sobre o cache há muitas maneiras de fazê-lo. O mais comum é o cache LRU. Há também uma alternativa que criei recentemente (link aqui ou aqui ) que permite que você airmazene mais imagens e evite ter OOM, mas que lhe dá muita responsabilidade.

    Você pode usair esse método paira passair a image e tirair um bitmap dele:

     public Bitmap decodeFile(File f) { Bitmap b = null; try { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; FileInputStream fis = new FileInputStream(f); BitmapFactory.decodeStream(fis, null, o); fis.close(); int IMAGE_MAX_SIZE = 1000; int scale = 1; if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) { scale = (int) Math.pow( 2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5))); } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; fis = new FileInputStream(f); b = BitmapFactory.decodeStream(fis, null, o2); fis.close(); } catch (IOException e) { e.printStackTrace(); } return b; } } public Bitmap decodeFile(File f) { Bitmap b = null; try { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; FileInputStream fis = new FileInputStream(f); BitmapFactory.decodeStream(fis, null, o); fis.close(); int IMAGE_MAX_SIZE = 1000; int scale = 1; if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) { scale = (int) Math.pow( 2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5))); } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; fis = new FileInputStream(f); b = BitmapFactory.decodeStream(fis, null, o2); fis.close(); } catch (IOException e) { e.printStackTrace(); } return b; } } public Bitmap decodeFile(File f) { Bitmap b = null; try { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; FileInputStream fis = new FileInputStream(f); BitmapFactory.decodeStream(fis, null, o); fis.close(); int IMAGE_MAX_SIZE = 1000; int scale = 1; if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) { scale = (int) Math.pow( 2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5))); } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; fis = new FileInputStream(f); b = BitmapFactory.decodeStream(fis, null, o2); fis.close(); } catch (IOException e) { e.printStackTrace(); } return b; } 

    @Ori Wasserman: conforme o seu request, usei um método paira obter imagens da pasta de resources e também usei uma image de 7 MB. Coloco a image de 7 MB na pasta "res-> drawable" e com o seguinte código não falhou e a image foi mostrada na imageview:

      Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.image_7mb); loBitmap = Bitmap.createScaledBitmap(image, width_of_screen , height_of_screen, true); imageview.setImageBitmap(loBitmap); 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.