Android Question OutOfMemory Error - Bitmaps

rafaelbr20

Member
Licensed User
Longtime User
Hi Everyone !

I´m getting the exception OutOfMemoryError! Please help me, i´m 5 days with this problem !!

I load bitmap once on "FirstTime", put it on Map and then use it, so when i call "Activity.Finish" this activity closes, and when i open it again, i get the exception OutOfMemoryError. Why if i don´t Load Bitmap again, i use the bitmaps i have puted on MAP variable.


Part of My COde

B4X:
Sub Process_Globals
    Dim mapImagensMiniaturas As Map
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Dim First as Boolean
    First = FirstTime
if FirstTime = True Then
    mapImagensMiniaturas.Initialize 'Inicialize only on FirstTime
End If
End Sub


Sub carregarScroolListaPersonagens
    ArrayPersonagens(0) = "galo_pq.png#galo_grd.png#Galo#Cock#galo.mp3"
    ArrayPersonagens(1) = "bode_pq.png#bode_grd.png#Bode#Billy-Goat#cabra.mp3"
    ArrayPersonagens(2) = "cavalo_pq.png#cavalo_grd.png#Cavalo#Horse#cavalo.mp3"
    ArrayPersonagens(3) = "ganso_pq.png#ganso_grd.png#Ganso#Goose#ganso.mp3"
    ArrayPersonagens(4) = "porco_pq.png#porco_grd.png#Porco#Pig#porco.mp3"
    ArrayPersonagens(5) = "vaca_pq.png#vaca_grd.png#Vaca#Cow#vaca.mp3"
    ArrayPersonagens(6) = "galinha_pq.png#galinha_grd.png#Galinha#Chicken#galinha.mp3"
    ArrayPersonagens(7) = "peru_pq.png#peru_grd.png#Peru#Turkey#peru.mp3"
    ArrayPersonagens(8) = "touro_pq.png#touro_grd.png#Touro#Taurus#touro.mp3"
    ArrayPersonagens(9) = "pato_pq.png#pato_grd.png#Pato#Duck#pato.mp3"
    ArrayPersonagens(10) = "ovelha_pq.png#ovelha_grd.png#Ovelha#Sheep#ovelha.mp3"

    For i = 0 To 10
        Dim imgPers As ImageView
        Dim dadosPersonagens(2) As String
        dadosPersonagens = Regex.Split("#", ArrayPersonagens(i))
        imgPers.Initialize("imgPers")
        imgPers.Tag = ArrayPersonagens(i)
        imgPers.Gravity = Gravity.FILL
 
If First= True Then
mapImagensMiniaturas.Put(i,LoadBitmapSample(File.DirAssets,dadosPersonagens(0),baseMod.larguraMiniauras,baseMod.larguraMiniauras)) 'I Execute LoadBitmapSample only on FirstTime and put it on Map variable
End If

        imgPers.Bitmap = mapImagensMiniaturas.GetValueAt(i) 'Use Bitmap from MAP
        scrwBarraCima.Panel.AddView(imgPers,leftPersonagemScrool,5,baseMod.larguraMiniauras,baseMod.larguraMiniauras)
     Next

END Sub


SEE LOG

FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:543)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:518)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:370)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
at android.content.res.Resources.loadDrawable(Resources.java:1970)
at android.content.res.Resources.getDrawable(Resources.java:676)
at uk.co.martinpearman.b4a.androidresources.AndroidResources.GetApplicationDrawable(AndroidResources.java:129)
at com.mobileforfunapps.descobrindomeumundo.basemod._buscarimagem(basemod.java:164)
at com.mobileforfunapps.descobrindomeumundo.frmquizzanimais._montarlayout(frmquizzanimais.java:931)
at com.mobileforfunapps.descobrindomeumundo.frmquizzanimais._activity_create(frmquizzanimais.java:334)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:174)
at com.mobileforfunapps.descobrindomeumundo.frmquizzanimais.afterFirstLayout(frmquizzanimais.java:98)
at com.mobileforfunapps.descobrindomeumundo.frmquizzanimais.access$100(frmquizzanimais.java:16)
at com.mobileforfunapps.descobrindomeumundo.frmquizzanimais$WaitForLayout.run(frmquizzanimais.java:76)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4624)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
at dalvik.system.NativeStart.main(Native Method)
threadid=86: interp stack at 0x4d30b000
threadid=86: calling run()
Force finishing activity com.mobileforfunapps.descobrindomeumundo/.frmquizzanimais


Thanks So Much

Rafael
 
Last edited:

rafaelbr20

Member
Licensed User
Longtime User
Please use [ code ] [ /code ] tags (without spaces) when posting code.

The problem is here:
uk.co.martinpearman.b4a.androidresources.AndroidResources.GetApplicationDrawable(AndroidResources.java:129)

You should load these drawables once.

Hi Erel,

Thanks so much ! You are correct ! I Fixed this problem.

Let me ask a question about Media Player, i´m using some MP3 files that has 800 Kb. When i use MediaPlayer.Load it goes to Memory too like LoadBitmapSample or not ?

I Would like to optimize my app.

PS: Sorry, the next time i´ll put the code inside tags.

Thanks so Much.

MY CODE

B4X:
Sub Activity_Create(FirstTime As Boolean)
If FirstTime = True Then
            MPFundoMar.Initialize2("MP")
            MPFundoMar.SetVolume(0.5,0.5)
            MPFundoMar.Load(File.DirAssets, "bolhasFundo.mp3")
            MPFundoMar.Looping = True
End If
End Sub
 
Last edited:
Upvote 0

rafaelbr20

Member
Licensed User
Longtime User
Hi Erel. Thanks again.

I´m still having problem with OutOfMemory.

How i wrote on first post, i´m keeping all bitmap on memory inside a MAP variable on Process Global area, so when user comes back to that activity i don´t need to Load Bitmap again.

But i have 5 activities and all of then is keeping the bitmaps on memory. If user open 1 or 2 activities is ok, but if he opens those 5 , the OutOfMemory happens.

I Think the best solution is when user close the activity ( Activity.Finish ), i´ll check it using Sub Activity_Pause (UserClosed = True ) and then Recycle all bitmaps from memory.

I saw some posts here using reflector.runMethod("recycle"), but my problem is that i create imageViews and load Bitmaps on it dinamically as you see bellow.

B4X:
For i = 0 To 11
        Dim imgPers As ImageView
        Dim dadosPersonagens(2) As String
        dadosPersonagens = Regex.Split("#", ArrayPersonagens(i))
        imgPers.Initialize("imgPers")
        imgPers.Tag = ArrayPersonagens(i)
        imgPers.Gravity = Gravity.FILL
        imgPers.Bitmap = LoadBitmapSample(File.DirAssets,dadosPersonagens(0),baseMod.larguraMiniauras,baseMod.larguraMiniauras)
        scrwBarraCima.Panel.AddView(imgPers,leftPersonagemScrool,5,baseMod.larguraMiniauras, baseMod.larguraMiniauras)
        scrwBarraCima.Panel.Width = scrwBarraCima.Panel.Width + baseMod.larguraMiniauras
        leftPersonagemScrool = leftPersonagemScrool + baseMod.larguraMiniauras + 10dip
    Next

So my question is, how can i clear all images i loaded into memory ?

If you prefer, i can upload the activity file.

Thanks so Much

Rafael
 
Last edited:
Upvote 0

rafaelbr20

Member
Licensed User
Longtime User
These posts are probably old or wrong. This won't change anything under Android >= Honeycomb.


Clear your map and set the Bitmap property of your ImageViews to Null.

Hi Informatix ! Thanks for your help.

I Did it already , see bellow !


B4X:
Sub Process_Globals
    Dim bitmapImgGrande As Bitmap
    Dim bitmapCaixaFundo As Bitmap
    Dim bitmapMiniatura As Bitmap
    Dim bitmapFundo As Bitmap
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed = True Then
        MPFundoMar.Pause
        Activity.Finish
        limparObjetosMemoria 'Clear Objects From Memory
    End If
End Sub

Sub carregarScroolListaPersonagens
    Dim leftPersonagemScrool As String = 5
    Dim ArrayPersonagens(12) As String
   
    'IMAGEM PEQUENA # IMAGEM GRANDE # PORTUGUES # INGLES
    ArrayPersonagens(0) = "peixe_pq.png#peixe_grd.png#Peixe#Fish"
    ArrayPersonagens(1) = "polvo_pq.png#polvo_grd.png#Polvo#Octopus"
    ArrayPersonagens(2) = "arraia_pq.png#arraia_grd.png#Arraia#Ray Fish"
    ArrayPersonagens(3) = "siri_pq.png#siri_grd.png#Siri#Crab"
    ArrayPersonagens(4) = "tartaruga_pq.png#tartaruga_grd.png#Tartaruga Marinha#Sea Turtle"
    ArrayPersonagens(5) = "tubarao_pq.png#tubarao_grd.png#Tubarão#Shark"
    ArrayPersonagens(6) = "estreladomar_pq.png#estreladomar_grd.png#Estrela do Mar#Starfish"
    ArrayPersonagens(7) = "baleia_pq.png#baleia_grd.png#Baleia#Whale"
    ArrayPersonagens(8) = "golfinho_pq.png#golfinho_grd.png#Golfinho#Dolphin"
    ArrayPersonagens(9) = "camarao_pq.png#camarao_grd.png#Camarão#Shrimp"
    ArrayPersonagens(10) = "cavalo-marinho_pq.png#cavalo-marinho_grd.png#Cavalo Marinho#Seahorse"
    ArrayPersonagens(11) = "lula_pq.png#lula_grd.png#Lula#Squid"
   
    For i = 0 To 11
        Dim dadosPersonagens(2) As String
        dadosPersonagens = Regex.Split("#", ArrayPersonagens(i))
        imgPers.Initialize("imgPers")
        imgPers.Tag = ArrayPersonagens(i)
        imgPers.Gravity = Gravity.FILL
                 bitmapMiniatura.InitializeSample(File.DirAssets,dadosPersonagens(0),baseMod.larguraMiniauras,baseMod.larguraMiniauras)
 
       imgPers.SetBackgroundImage(bitmapMiniatura)
        scrwBarraCima.Panel.AddView(imgPers,leftPersonagemScrool,5,baseMod.larguraMiniauras, baseMod.larguraMiniauras)
        scrwBarraCima.Panel.Width = scrwBarraCima.Panel.Width + baseMod.larguraMiniauras
        leftPersonagemScrool = leftPersonagemScrool + baseMod.larguraMiniauras + 10dip
    Next
    scrwBarraCima.Panel.Width = scrwBarraCima.Panel.Width + (baseMod.larguraMiniauras * 2)
End Sub

Sub limparObjetosMemoria 'Clear Objects From Memory
     If imgGrd.IsInitialized Then imgGrd.SetBackgroundImage(Null)
     If imgPers.IsInitialized Then imgPers.SetBackgroundImage(Null)
     Activity.SetBackgroundImage(Null)
     If caixaFundoTexto.IsInitialized Then caixaFundoTexto.SetBackgroundImage(Null)
     If bitmapImgGrande.IsInitialized Then recycleObjeto(bitmapImgGrande)
     If bitmapCaixaFundo.IsInitialized Then recycleObjeto(bitmapCaixaFundo)
     If bitmapMiniatura.IsInitialized Then recycleObjeto(bitmapMiniatura)
     If bitmapFundo.IsInitialized Then recycleObjeto(bitmapFundo)
     Dim r As Reflector
     r.RunStaticMethod("java.lang.System", "gc", Null, Null)
     Log("Possivel limpeza")
End Sub

Sub recycleObjeto(imagem As Bitmap)
     Dim ref As Reflector
     ref.Target = imagem
     ref.RunMethod("recycle")
End Sub
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Hi Informatix ! Thanks for your help.

I Did it already , see bellow !


B4X:
Sub Process_Globals
    Dim bitmapImgGrande As Bitmap
    Dim bitmapCaixaFundo As Bitmap
    Dim bitmapMiniatura As Bitmap
    Dim bitmapFundo As Bitmap
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed = True Then
        MPFundoMar.Pause
        Activity.Finish
        limparObjetosMemoria 'Clear Objects From Memory
    End If
End Sub

Sub carregarScroolListaPersonagens
    Dim leftPersonagemScrool As String = 5
    Dim ArrayPersonagens(12) As String

    'IMAGEM PEQUENA # IMAGEM GRANDE # PORTUGUES # INGLES
    ArrayPersonagens(0) = "peixe_pq.png#peixe_grd.png#Peixe#Fish"
    ArrayPersonagens(1) = "polvo_pq.png#polvo_grd.png#Polvo#Octopus"
    ArrayPersonagens(2) = "arraia_pq.png#arraia_grd.png#Arraia#Ray Fish"
    ArrayPersonagens(3) = "siri_pq.png#siri_grd.png#Siri#Crab"
    ArrayPersonagens(4) = "tartaruga_pq.png#tartaruga_grd.png#Tartaruga Marinha#Sea Turtle"
    ArrayPersonagens(5) = "tubarao_pq.png#tubarao_grd.png#Tubarão#Shark"
    ArrayPersonagens(6) = "estreladomar_pq.png#estreladomar_grd.png#Estrela do Mar#Starfish"
    ArrayPersonagens(7) = "baleia_pq.png#baleia_grd.png#Baleia#Whale"
    ArrayPersonagens(8) = "golfinho_pq.png#golfinho_grd.png#Golfinho#Dolphin"
    ArrayPersonagens(9) = "camarao_pq.png#camarao_grd.png#Camarão#Shrimp"
    ArrayPersonagens(10) = "cavalo-marinho_pq.png#cavalo-marinho_grd.png#Cavalo Marinho#Seahorse"
    ArrayPersonagens(11) = "lula_pq.png#lula_grd.png#Lula#Squid"

    For i = 0 To 11
        Dim dadosPersonagens(2) As String
        dadosPersonagens = Regex.Split("#", ArrayPersonagens(i))
        imgPers.Initialize("imgPers")
        imgPers.Tag = ArrayPersonagens(i)
        imgPers.Gravity = Gravity.FILL
                 bitmapMiniatura.InitializeSample(File.DirAssets,dadosPersonagens(0),baseMod.larguraMiniauras,baseMod.larguraMiniauras)

       imgPers.SetBackgroundImage(bitmapMiniatura)
        scrwBarraCima.Panel.AddView(imgPers,leftPersonagemScrool,5,baseMod.larguraMiniauras, baseMod.larguraMiniauras)
        scrwBarraCima.Panel.Width = scrwBarraCima.Panel.Width + baseMod.larguraMiniauras
        leftPersonagemScrool = leftPersonagemScrool + baseMod.larguraMiniauras + 10dip
    Next
    scrwBarraCima.Panel.Width = scrwBarraCima.Panel.Width + (baseMod.larguraMiniauras * 2)
End Sub

Sub limparObjetosMemoria 'Clear Objects From Memory
     If imgGrd.IsInitialized Then imgGrd.SetBackgroundImage(Null)
     If imgPers.IsInitialized Then imgPers.SetBackgroundImage(Null)
     Activity.SetBackgroundImage(Null)
     If caixaFundoTexto.IsInitialized Then caixaFundoTexto.SetBackgroundImage(Null)
     If bitmapImgGrande.IsInitialized Then recycleObjeto(bitmapImgGrande)
     If bitmapCaixaFundo.IsInitialized Then recycleObjeto(bitmapCaixaFundo)
     If bitmapMiniatura.IsInitialized Then recycleObjeto(bitmapMiniatura)
     If bitmapFundo.IsInitialized Then recycleObjeto(bitmapFundo)
     Dim r As Reflector
     r.RunStaticMethod("java.lang.System", "gc", Null, Null)
     Log("Possivel limpeza")
End Sub

Sub recycleObjeto(imagem As Bitmap)
     Dim ref As Reflector
     ref.Target = imagem
     ref.RunMethod("recycle")
End Sub
You should call limparObjetosMemoria before Activity.Finish.
Apart this, I see nothing else to do in your code.
You can save a few extra kilobytes (or a lot more depending on the size of your images) by using LoadScaledBitmap of the Accelerated Surface lib instead of LoadBitmapSample. And you won't have to use Gravity.Fill for your ImageViews if you size correctly the image.
 
Upvote 0

rafaelbr20

Member
Licensed User
Longtime User
Wait before you remove the bitmaps. Can you post the error message?

Hi Erel and Informatix,

I´m attaching on this reply my 2 activities file.

The problem is, i have 4 activities like "frmFundoMar.bas", if i open those four and then open the activitie "frmquebraCabecas.bas" the Error occurs.

Informatix, this code in "frmquebraCabecas.bas" is your Puzzle example, thanks a lot it helps me a lot, but i´m having this problem , the problem occurs there.

Thats why i´m trying to clear memomry when i close the activity "frmquebraCabecas.bas" and others

I Really appreciate if you guys can take a look on my activities code.

Thanks so Much Again, for the Help !!

LOG

java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
at android.graphics.Bitmap.createBitmap(Bitmap.java:585)
at anywheresoftware.b4a.objects.drawable.CanvasWrapper.Initialize(CanvasWrapper.java:76)
at com.mobileforfunapps.descobrindomeumundo.frmquebracabecas._loadapicture(frmquebracabecas.java:896)
at com.mobileforfunapps.descobrindomeumundo.frmquebracabecas._carregarquebracabeca(frmquebracabecas.java:463)
at com.mobileforfunapps.descobrindomeumundo.frmquebracabecas._setarnivel(frmquebracabecas.java:1247)
at com.mobileforfunapps.descobrindomeumundo.frmquebracabecas._cliquebotaonivel(frmquebracabecas.java:470)
at com.mobileforfunapps.descobrindomeumundo.frmquebracabecas._imgnivelfacil_click(frmquebracabecas.java:695)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:174)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:162)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:158)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:66)
at android.view.View.performClick(View.java:3517)
at android.view.View$PerformClick.run(View.java:14155)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4624)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
at dalvik.system.NativeStart.main(Native Method)
 

Attachments

  • forms.zip
    10.8 KB · Views: 166
Upvote 0

rafaelbr20

Member
Licensed User
Longtime User
Hi Erel and Informatix !

I Solved my problem setting every bitmap to NULL on Activity_Pause (Userclosed = True) !

B4X:
imgBtnVoltar.Bitmap = Null
imgBtnDireita.Bitmap = Null
imgBtnEsquerda.Bitmap = Null
Activity.SetBackgroundImage(Null)

Dim r As Reflector
r.RunStaticMethod("java.lang.System", "gc", Null, Null)

Thanks so Much !
 
Upvote 0

eps

Expert
Licensed User
Longtime User
You should test your App on Samsung devices, these arenotoriously stingey when it comes to dishing out App memory.
 
Upvote 0
Top