Android – La cache bitmap richiede molta memory

Sono nuovo a tutto il sobject della gestione della memory, quindi ci sono molte cose che non capisco.
Sto cercando di memorizzare un'image nella mia app, ma ho problemi con il suo consumo di memory:

Tutto il codice di Chipping Bitmap è praticamente copiato da qui: http://developer.android.com/training/displaying-bitmaps/index.html

  • Come salvare la posizione di scorrimento di RecyclerView in Android?
  • codifica UTF8 android dalla string ricevuta
  • Passare i dati a BroadcastReceiver da attività utilizzando DownloadManager
  • Emulatore Android appeso all'avvio?
  • Utilizzando la libreria volley, all'interno del metodo onResponse, l'ArrayList ha alcuni dati ma al di fuori del metodo OnResponse l'architetto è vuoto
  • java.text.ParseException: data irripetibile
  • Ho eseguito il debug del codice e controllato la dimensione del mucchio nella vista DDMS in eclipse e ci sono circa 15 MB di salto dopo queste righe di codice:

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

    nel metodo "decodeSampledBitmapFromResource".

    L'image è 1024×800, 75kb jpg file. Secondo quello che ho già visto su internet, la quantità di memory che questa image dovrebbe assumere è di circa 1024 * 800 * 4 (Bytes per pixel) = 3.125mb

    Tutti i fatti relativi a questo argomento non dicono perché sta prendendo molto più memory di quanto non dovrebbe. C'è un modo per cache un'image con una quantità ragionevole di memory?

    EDIT

    Ho provato a utilizzare il metodo decodeFile suggerito alla risposta di @ ArshadParwez qui sotto. Utilizzando questo metodo, dopo il metodo BitmapFactory.decodeStream la memory viene aumentata di solo 3,5mb – risolto il problema, ma voglio eseguire la cache delle bitmap direttamente dalla risorsa.

    Ho notato che durante il metodo decodeResource ci sono 2 "salti" di memory – uno di circa 3,5mb – che è ragionevole e un altro strano di 14mb. Quali sono i 14 MB utilizzati e perché questo accade?

  • Android Studio Gradle si blocca durante il caricamento del vecchio progetto gradel
  • Come catturare l'input soft della tastiera in una vista?
  • il mio onNewIntent non sta chiamando
  • Colonna mancante sqlite di Android
  • Applicazione semplice di android con i robot che lanciano le eccezioni
  • Registri audio su Android con MediaPlayer come sorgente?
  • 3 Solutions collect form web for “Android – La cache bitmap richiede molta memory”

    Le immagini vengono scalate in base alla densità in modo da poter utilizzare un sacco di memory.

    Ad esempio, se il file image è nella cartella drawable (che è densità mdpi ) e lo si esegue su un dispositivo xhdpi , sia la width che l'altezza raddoppieranno. Forse questo collegamento potrebbe aiutarti, o questo .

    Quindi nell'esempio i byte che il file di image avrebbe preso sono:

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

    Sarebbe ancora peggiore se l'avresti eseguito su un dispositivo xxhdpi (come quello HTC e Galaxy S4).

    Cosa sai fare? Posizionare il file image nella cartella densità corretta ( drawable-xhdpi o drawable-xxhdpi ) oppure metterla in drawable-nodpi (o nella cartella asset) e ridimensionare l'image secondo le tue esigenze.

    BTW non è necessario impostare options.inJustDecodeBounds = false poiché è il comportmento predefinito. Infatti puoi impostare null per le opzioni bitmap.

    Per quanto riguarda la scalatura in basso è ansible utilizzare il modo google o la mia strada ciascuno ha i suoi vantaggi e svantaggi.

    Su caching ci sono molti modi per farlo. La più comune è la cache LRU. C'è anche un'alternativa che ho creato recentemente (collegamento qui o qui ) che ti consente di memorizzare più immagini e evitare di avere OOM, ma ti dà molta responsabilità.

    È ansible utilizzare questo metodo per passare l'image e get un bitmap da esso:

     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: Come per la tua richiesta ho usato un metodo per get le immagini dalla cartella di risorse e anche io ho usato un'image di 7 MB. Ho messo l'image di 7 MB nella cartella "res-> drawable" e con il seguente codice non si è arrestato e l'image è stata visualizzata nell'image:

      Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.image_7mb); loBitmap = Bitmap.createScaledBitmap(image, width_of_screen , height_of_screen, true); imageview.setImageBitmap(loBitmap); 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.