Autore Topic: problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,  (Letto 4372 volte)

Offline davidino81

  • Utente junior
  • **
  • Post: 66
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc one v
  • Sistema operativo:
    Windows 7
Ciao a tutti!Ho un problema con la memoria nella mia app perché non so come liberare la memoria.
Ho letto molte guide ma tutte si riferiscono a immagini Bitmap e non vorrei complicarmi le cose.
Grazie in anticipo


Codice (Java): [Seleziona]
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
                       
                        if (ling2.equals("ita")){
                                getWindow().setBackgroundDrawableResource(R.drawable.ita_port);

                        }
                        else if(ling2.equals("eng")){
                                getWindow().setBackgroundDrawableResource(R.drawable.eng_main_port);
etc......

ACRA:

STACK_TRACE=java.lang.OutOfMemoryError: (Heap Size=65159KB, Allocated=56814KB)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:626)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:473)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:781)
at android.content.res.Resources.loadDrawable(Resources.java:1959)
at android.content.res.Resources.getDrawable(Resources.java:667)
at android.view.Window.setBackgroundDrawableResource(Window.java:1039)
at com.imparavocabolieverbi.MainActivity.set_background(MainActivity.java:686)
at com.imparavocabolieverbi.MainActivity.onCreate(MainActivity.java:176)
at android.app.Activity.performCreate(Activity.java:5066)

LogCat:

02-14 11:08:45.460 I/dalvikvm-heap(21195): Forcing collection of SoftReferences for 8775016-byte allocation
02-14 11:08:45.500 E/dalvikvm-heap(21195): Out of memory on a 8775016-byte allocation.
02-14 11:08:45.500 I/dalvikvm(21195): "main" prio=5 tid=1 RUNNABLE
02-14 11:08:45.500 I/dalvikvm(21195):   | group="main" sCount=0 dsCount=0 obj=0x414786d0 self=0x4011e018
02-14 11:08:45.500 I/dalvikvm(21195):   | sysTid=21195 nice=0 sched=0/0 cgrp=apps handle=1074694192
02-14 11:08:45.500 I/dalvikvm(21195):   | schedstat=( 0 0 0 ) utm=221 stm=79 core=1
02-14 11:08:45.500 I/dalvikvm(21195):   at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:626)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:473)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:781)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.content.res.Resources.loadDrawable(Resources.java:1959)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.content.res.Resources.getDrawable(Resources.java:667)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.view.Window.setBackgroundDrawableResource(Window.java:1039)
02-14 11:08:45.500 I/dalvikvm(21195):   at com.imparavocabolieverbi.MainActivity.set_background(MainActivity.java:686)
02-14 11:08:45.500 I/dalvikvm(21195):   at com.imparavocabolieverbi.MainActivity.onCreate(MainActivity.java:176)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.app.Activity.performCreate(Activity.java:5066)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1101)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2307)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4032)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.app.ActivityThread.access$700(ActivityThread.java:151)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1337)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.os.Handler.dispatchMessage(Handler.java:99)
02-14 11:08:45.500 I/dalvikvm(21195):   at android.os.Looper.loop(Looper.java:155)

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #1 il: 14 Febbraio 2013, 14:27:02 CET »
0
Ma quanto grande è l'immagine che stai cercando di impostare come sfondo?  o_O

Offline davidino81

  • Utente junior
  • **
  • Post: 66
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc one v
  • Sistema operativo:
    Windows 7
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #2 il: 14 Febbraio 2013, 16:08:27 CET »
0
80Kb, ho provato anche a renderla mene pesante ma il problema rimane

Offline davidino81

  • Utente junior
  • **
  • Post: 66
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc one v
  • Sistema operativo:
    Windows 7
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #3 il: 14 Febbraio 2013, 16:20:22 CET »
0
Come si fa a disallocare la memoria occupata da una immagine ?

Offline elfo83

  • Utente normale
  • ***
  • Post: 283
  • Respect: +23
    • Mostra profilo
  • Sistema operativo:
    Mac OS 10.8.2

Offline davidino81

  • Utente junior
  • **
  • Post: 66
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc one v
  • Sistema operativo:
    Windows 7
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #5 il: 14 Febbraio 2013, 17:31:32 CET »
0
Io ho un jpg però non un bitmap

Offline elfo83

  • Utente normale
  • ***
  • Post: 283
  • Respect: +23
    • Mostra profilo
  • Sistema operativo:
    Mac OS 10.8.2
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #6 il: 14 Febbraio 2013, 17:40:04 CET »
0
Dichiari un oggetto di tipo:
private BitmapDrawable drawable;

gli associa la tua immagine che avrai nella cartella drawable
drawable=getResources().getDrawable(R.drawable.nomeTuaImmagine)

recicli in questo modo:

drawable.getBitmap().recycle();

Offline davidino81

  • Utente junior
  • **
  • Post: 66
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc one v
  • Sistema operativo:
    Windows 7
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #7 il: 14 Febbraio 2013, 18:06:34 CET »
0
Ciao elfo83,
grazie mille per la risposta ma non ho risolto, con quel metodo riesco a cariare l'immagine ma quando uso :
drawable.getBitmap().recycle();
in onPause() o in onDestroy va in crash con questo errore:
unable to pause activity, java.lang.NullPointerException

Offline elfo83

  • Utente normale
  • ***
  • Post: 283
  • Respect: +23
    • Mostra profilo
  • Sistema operativo:
    Mac OS 10.8.2
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #8 il: 14 Febbraio 2013, 18:21:44 CET »
0
Di solito le immagini si riciclano o all'interno del codice dell'Attività (ad esempio se usi 4 immagini quando l'attività parte e poi non le usi +, puoi pensare di riciclarle una volta che sei sicuro che non ti servono +) oppure nel metodo onDestroy, quando l'attività è finita è o distrutta. Ti consiglio quindi di non riciclare in onPause perché, nel tuo caso, a runtine si cercano i riferimenti alle immagini che ricicli che sono nulli. Quindi puoi ad esempio creare un metodo all'interno del tuo codice, che ricicla le immagini, in un punto specifico di esecuzione, o puoi chiamare in onDestroy() il metodo unbindDrawables(View view) a cui passerai la radice del tuo file xml e in questo modo ricicla tutti gli elementi che sono specificati in questo metodo. Nel mio caso sono riciclati:
imageView, i background,listView e ViewGroup con i relativi figli. Tu ovviamente puoi aggiungere od omettere elementi.
Nel tuo metodo onDestroy basta fare:
Codice (Java): [Seleziona]
  unbindDrawables(findViewById(R.id.IdDellaRadiceDelTuoLayoutXml));
Codice (Java): [Seleziona]
protected void unbindDrawables(View view) {
                if(view==null)
                        return;
        if(view instanceof ImageView)
        {
                if(((ImageView) view).getDrawable()!=null)
                        ((ImageView) view).getDrawable().setCallback(null);
        }
        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));
            }
            if(!((view instanceof ListView) || ( view instanceof Spinner)))
                ((ViewGroup) view).removeAllViews();
           
        }
    }

Offline davidino81

  • Utente junior
  • **
  • Post: 66
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc one v
  • Sistema operativo:
    Windows 7
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #9 il: 14 Febbraio 2013, 18:50:39 CET »
0
Creando il metodo è riciclando i background posso lasciare le immagini in jpg o è meglio caricarle e trasformarle in Bitmap?
grazie mille

Offline elfo83

  • Utente normale
  • ***
  • Post: 283
  • Respect: +23
    • Mostra profilo
  • Sistema operativo:
    Mac OS 10.8.2
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #10 il: 14 Febbraio 2013, 20:27:02 CET »
+1
Secondo me non ti sono chiari alcuni concetti...
Premetto che ti conviene usare immagini in formato .png

Quando usi un oggetto di tipo BitmapDrawable o Bitmap lo fai puntare ad una tua risorsa, in questo caso alla tuaImmagine.jpg. Quando ricicli la tua BitmapDrawable stai dicendo che vuoi eliminare tutti i riferimenti tra l'oggetto BitmapDrawable e la tuaImmagine.jpg. Infatti, se dopo aver riciclato la la BitmapDrawable invochi ad esempio il metodo

NomeOggettoBitmapDrawable.getBitmap().getHeight()

otterrai un errore. Tutte le risorse che stai usando, come ad esempio immagini o video, rimangono sempre nelle cartelle del tuo progetto, quello che cambia è gli oggetti che dichiari in java che puntano a quelle risorse. E' meglio se il metodo unbindDrawables(r.id.idLayoutRadiceFileXml) lo metti sempre in onDestroy(), cambiando ovviamente il suo contenuto a seconda degli oggetti che stai manipolando e che vuoi rilasciare. Subito dopo, sempre in onDestroy() chiami System.gc; per sollecitare la garbage collector che si occupa di eliminare la memoria degli oggetti non referenziati. Inoltre, come ho scritto prima, puoi creare il tuo metodo che invochi in un punto preciso del codice se vuoi riciclare immagini che magari usi per i primi 2 secondi dell'attività.

Offline davidino81

  • Utente junior
  • **
  • Post: 66
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc one v
  • Sistema operativo:
    Windows 7
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #11 il: 15 Febbraio 2013, 21:58:07 CET »
0
Non riesco a risolvere il  problema, ho provato sia con drawable.getBitmap().recycle(); che con   unbindDrawables(findViewById(R.id.IdDellaRadiceDelTuoLayoutXml));
Adesso spiego meglio il funzionamento dell'activity:
In onCreate viene chiamato il metodo :

Codice (Java): [Seleziona]
public void set_background(){
                prefs=  getSharedPreferences("set language", Context.MODE_PRIVATE);
                String ling2 = prefs.getString("ling2", "no");
                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
                        if (ling2.equals("ita")){
                                drawable=(BitmapDrawable) getResources().getDrawable(R.drawable.ita_main_port);
                        }
                        else if(ling2.equals("eng")){
                                drawable=(BitmapDrawable) getResources().getDrawable(R.drawable.eng_main_port);
                        }
..
..
                getWindow().setBackgroundDrawable(drawable);
}
Dopo aver selezionato lo sfondo la activity rimane in attesa che l'utente prema un pulsante, tutti i pulsanti caricano un'altra activity eccetto uno che si occupa di cambiare lo sfondo richiamando la funzione sopra (non viene quindi ricreata l'activity ma cambia solo lo sfondo).
Se invece ruoto il cel l'activity viene distrutta e ricreata.
Non so come fare, mi va in crash sia quando cambio lo sfondo che quando la activity si ricrea dopo un Intent da un altra activity; non va subito in crash ma dopo un po di utilizzo ma comunque sempre  quando usa il metodo sopra.
Qualcuno sa come aiutarmi ? I metodi sopracitati non hanno funzionato.
Grazie a tutti

Offline elfo83

  • Utente normale
  • ***
  • Post: 283
  • Respect: +23
    • Mostra profilo
  • Sistema operativo:
    Mac OS 10.8.2
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #12 il: 15 Febbraio 2013, 23:33:32 CET »
0
prova a fare il copia e incolla del tuo errore in logcat

Offline davidino81

  • Utente junior
  • **
  • Post: 66
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc one v
  • Sistema operativo:
    Windows 7
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #13 il: 16 Febbraio 2013, 09:20:58 CET »
0
Questo è il logcat, ieri però ho fatto un'altra scoperta:
Facendo girare l'app in debug ed analizzando le variabili con watch mi sono accorto che usa delle dimensioni esagerate, l'immagine a cui punta è un jpg (o provato anche con png) di dimensioni 750x1300 a 72dp 123Kb, il mio cel ha uno schermo di 540x960 ma la variabile drawable quando l'app gira sul cel ha:

mBitmapSize:8775000
mNativeBitmap:1409720456
mWidth:1125
mHeight:1950
Density 240

Se la faccio girare sull'emulatore ottengo :

mBitmapSize: Non lo indica
mNativeBitmap:1214280
mWidth:1125
mHeight:1950
Density 240

Ho provato con photoshop e la stessa immagini jpg sopra indicata se la faccio Bitmap con le dimensioni 1125x1950 ha un peso di 6,67 MB.
Le altre immagini le uso come sfondi di imageButton quindi con dimensione definite nell'xml, in quel caso NON ho problemi di dimensioni e peso.

Perché se uso le immagini come sfondo
Codice (Java): [Seleziona]
drawable=(BitmapDrawable)getResources().getDrawable(R.drawable.eng_main_land);
getWindow().setBackgroundDrawable(drawable);
   
mi mette queste dimensioni assurde ?

Codice: [Seleziona]
02-15 14:22:06.378 I/ME      (25860): entrato in set_background da main
02-15 14:22:06.378 I/ME      (25860): entrato in set_background da main entra in portrait
02-15 14:22:06.438 I/dalvikvm-heap(25860): Forcing collection of SoftReferences for 3900016-byte allocation
02-15 14:22:06.488 E/dalvikvm-heap(25860): Out of memory on a 3900016-byte allocation.
02-15 14:22:06.488 I/dalvikvm(25860): "main" prio=5 tid=1 RUNNABLE
02-15 14:22:06.488 I/dalvikvm(25860):   | group="main" sCount=0 dsCount=0 obj=0x414786d0 self=0x4011e018
02-15 14:22:06.488 I/dalvikvm(25860):   | sysTid=25860 nice=0 sched=0/0 cgrp=apps handle=1074694192
02-15 14:22:06.488 I/dalvikvm(25860):   | schedstat=( 0 0 0 ) utm=2958 stm=393 core=0
02-15 14:22:06.488 I/dalvikvm(25860):   at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:626)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:473)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:781)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.content.res.Resources.loadDrawable(Resources.java:1959)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.content.res.Resources.getDrawable(Resources.java:667)
02-15 14:22:06.488 I/dalvikvm(25860):   at com.imparavocabolieverbi.MainActivity.set_background(MainActivity.java:777)
02-15 14:22:06.488 I/dalvikvm(25860):   at com.imparavocabolieverbi.MainActivity$3.onClick(MainActivity.java:358)
02-15 14:22:06.488 I/dalvikvm(25860):   at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:980)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.widget.AdapterView.performItemClick(AdapterView.java:298)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.widget.AbsListView.performItemClick(AbsListView.java:1150)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.widget.ListView.performItemClick(ListView.java:4397)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.widget.AbsListView$PerformClick.run(AbsListView.java:2985)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.widget.AbsListView$1.run(AbsListView.java:3671)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.os.Handler.handleCallback(Handler.java:615)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.os.Handler.dispatchMessage(Handler.java:92)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.os.Looper.loop(Looper.java:155)
02-15 14:22:06.488 I/dalvikvm(25860):   at android.app.ActivityThread.main(ActivityThread.java:5454)
02-15 14:22:06.488 I/dalvikvm(25860):   at java.lang.reflect.Method.invokeNative(Native Method)
02-15 14:22:06.488 I/dalvikvm(25860):   at java.lang.reflect.Method.invoke(Method.java:511)
02-15 14:22:06.488 I/dalvikvm(25860):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
02-15 14:22:06.488 I/dalvikvm(25860):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
02-15 14:22:06.488 I/dalvikvm(25860):   at dalvik.system.NativeStart.main(Native Method)
02-15 14:22:06.488 I/dalvikvm(25860):
02-15 14:22:06.498 E/dalvikvm(25860): Out of memory: Heap Size=65543KB, Allocated=55120KB, Limit=65536KB
02-15 14:22:06.498 E/dalvikvm(25860): Extra info: Footprint=65543KB, Allowed Footprint=65543KB, Trimmed=14444KB
02-15 14:22:06.498 W/dalvikvm(25860): threadid=1: thread exiting with uncaught exception (group=0x41477468)
02-15 14:22:06.498 E/ACRA    (25860): ACRA caught a OutOfMemoryError exception for com.imparavocabolieverbi. Building report.
02-15 14:22:06.528 I/ACRA    (25860): READ_LOGS granted! ACRA can include LogCat and DropBox data.

Offline davidino81

  • Utente junior
  • **
  • Post: 66
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    htc one v
  • Sistema operativo:
    Windows 7
Re:problema con sfondo jpg (java.lang.OutOfMemoryError: (Heap Size=65159KB,
« Risposta #14 il: 18 Febbraio 2013, 14:47:30 CET »
0
Ho capito qualcosa in più ma non ho risolto tutti i problema.
Ho utilizzato un solo drawable senza ridimensionarli quindi per android il mio file era per gli schermi mdpi quindi lo aumentava di 0.5 per arrivare a hdpi come il mio cel, da qui si passa da 1300 a 1950 con dimensioni in Bitmap di 8MB.
Il mio problema adesso è decidere come salvare le immagini, che densità e dimensioni mi conviene usare per lmdp, mdpi etc.. ?