2012-09-12 7 views
6

Sto usando un'immagine da impostare come sfondo per tutte le mie attività ma causava un problema di overflow di memoria e bloccava l'app. Ora sto disancorando i miei drawable su pause() e su Destroy() nella mia attività e ora mostra lo schermo vuoto premendo il pulsante indietro. Quindi, come posso evitarlo senza usare memoria extra.Disattivare i drawable onPause() causando una mancata risposta alla navigazione indietro e saltare questo passaggio causano un overflow di memoria

protected void onPause(){ 
    super.onPause(); 
    unbindDrawables(findViewById(R.id.login_root)); 
} 

protected void onDestroy() { 
     unbindDrawables(findViewById(R.id.login_root)); 
     super.onDestroy(); 
     } 

private void unbindDrawables(View view) { 
    System.gc(); 
    Runtime.getRuntime().gc(); 
    if (view.getBackground() != null) { 
    view.getBackground().setCallback(null); 
    } 
    if (view instanceof ViewGroup) { 
     for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
     unbindDrawables(((ViewGroup) view).getChildAt(i)); 
     } 
    ((ViewGroup) view).removeAllViews(); 
    } 

Inizialmente ero gonfiare il mio layout utilizzando Android: background = "@ drawable /", che sempre causato l'errore di overflow di memoria dicendo che VM non ci permetterà di allocare 10 MB Ora sto ottenendo una bitmap da (app.) quel drawable senza ridimensionarlo e legarlo in runtime. Ora dice che VM non ci permetterà di allocare 5MB (app) senza usare unbindDrawables (..) Ovviamente la qualità dell'immagine di sfondo che viene mostrata è diminuita ma non sono in grado per capire che se sto usando un file PNG di 13 KB, come fa JVM a richiedere 5 o 10 MB di spazio per elaborare la richiesta?

Ho spostato le mie istruzioni di layout da onCreate() al metodo onResume() ma l'applicazione ha di nuovo esaurito la memoria premendo il pulsante Indietro.

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    protected void onResume(){ 
     setContentView(R.layout.home); 
     Bitmap bmp; 
     ImageView background = (ImageView)findViewById(R.id.iv_home_background); 
     InputStream is = getResources().openRawResource(R.drawable.background); 
     bmp = BitmapFactory.decodeStream(is); 
     background.setImageBitmap(bmp); 

     super.onResume(); 
    } 

protected void onPause(){ 
     super.onPause(); 
     unbindDrawables(findViewById(R.id.home_root)); 
    } 


private void unbindDrawables(View view) { 
     System.gc(); 
     Runtime.getRuntime().gc(); 
     if (view.getBackground() != null) { 
     view.getBackground().setCallback(null); 
     } 
     if (view instanceof ViewGroup) { 
      for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
      unbindDrawables(((ViewGroup) view).getChildAt(i)); 
      } 
     ((ViewGroup) view).removeAllViews(); 
     } 
    } 
+0

Ricordare che se onDestroy() viene chiamato, onPause() viene chiamato anche in precedenza. –

+0

unbind solo in 'onPause()' come dichiarato da @JohnSatriano. Ma ancora, mostraci la tua funzione onResume –

+0

Non ho eseguito l'override sulla mia funzione di ripresa. Non ho assolutamente idea di cosa fare lì. – Atinder

risposta

1

Ho trovato una soluzione per questo problema. Ora sto ridimensionando le mie bitmap in fase di esecuzione a dimensioni molto ridotte e quindi memorizzandole nella memoria interna. Il programma richiama le immagini bitmap ridimensionate dalla memoria in fase di esecuzione e, se non è presente, lo chiama dalla cartella disegnabile, lo ridimensiona, lo scrive nell'archivio e quindi lo associa alla vista. In questo modo non è necessario chiamare il metodo unbindDrawables in qualsiasi momento e l'applicazione rimane reattiva per tutto il tempo. La mia unica preoccupazione al momento è la qualità dei bitmap, penso di aver bisogno di giocare con le dimensioni del ridimensionamento per trovare la dimensione minima possibile con la massima qualità.

0

Si sta chiamando GC per ogni vista secondaria. Prova a chiamarlo solo una volta quando tutti i follower sono terminati.

unbindDrawables(findViewById(R.id.login_root)); 
System.gc(); 

GC è un carico pesante ed è inutile chiamarlo troppo spesso. infatti, se non ci sono perdite, dovrebbe essere nesiano.

Inoltre, tenere presente che le dimensioni dei file PNG non hanno nulla a che fare con una bitmap sulla memoria. Ecco ulteriori informazioni su questo http://developer.android.com/training/displaying-bitmaps/index.html

Problemi correlati