Android Question OutOfMemory Error with GifDecoder and GifViewer

Christian García S.

Active Member
Licensed User
Hello everyone,

I implemented a splash screen when app is started, all works fine in my phone test (Samsung S8 Android 8), I published that app to Google Play but when the app is loaded in other phones with minor characteristics the app crash.

I used for this Library GifDecoder and Class GifViewer, I can checked logs in developer console and I got this:

B4X:
java.lang.OutOfMemoryError

en com.company.name.gifviewer._setgif

The app crash in this Phone with Android 6 (LGE LG K8 (mm1v), 1536MB RAM, Android 6.0)

B4X:
java.lang.OutOfMemoryError:
  at dalvik.system.VMRuntime.newNonMovableArray (Native Method)
  at android.graphics.Bitmap.nativeCreate (Native Method)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:904)
  at android.graphics.Bitmap.createBitmap (Bitmap.java:928)
  at anywheresoftware.b4a.agraham.gifdecoder.GifDecoder.SetPixels (GifDecoder.java:298)
  at anywheresoftware.b4a.agraham.gifdecoder.GifDecoder.SetPixels (GifDecoder.java:396)
  at anywheresoftware.b4a.agraham.gifdecoder.GifDecoder.ReadImage (GifDecoder.java:805)
  at anywheresoftware.b4a.agraham.gifdecoder.GifDecoder.ReadContents (GifDecoder.java:672)
  at anywheresoftware.b4a.agraham.gifdecoder.GifDecoder.Read (GifDecoder.java:559)
  at anywheresoftware.b4a.agraham.gifdecoder.GifDecoder.Load (GifDecoder.java:211)
  at com.company.name.gifviewer._setgif (gifviewer.java:150)
  at com.company.name.main._activity_create (main.java:386)
  at java.lang.reflect.Method.invoke (Native Method)
  at anywheresoftware.b4a.BA.raiseEvent2 (BA.java:186)
  at com.company.name.main.afterFirstLayout (main.java:107)
  at com.company.name.main.access$000 (main.java:20)
  at com.company.name.main$WaitForLayout.run (main.java:85)
  at android.os.Handler.handleCallback (Handler.java:739)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:148)
  at android.app.ActivityThread.main (ActivityThread.java:5551)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:731)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:621)

Can you help me with this ??

Thanks a lot
 

Peter Simpson

Expert
Licensed User
Hiya Christian,
Try loading bitmaps by using

B4X:
LoadBitmapSample

Instead of using

B4X:
LoadBitmap

Don't reload bitmaps multiple times, store any bitmaps that you may reuse multiple times in global veriables in the starter service.

If you are still having memory issues after that, you could also try increasing the heap memory size. To increase the heap size just add he following line into the manifest file.

B4X:
SetApplicationAttribute(android:largeHeap,"true")

Enjoy...
 
Last edited:
Upvote 0

Christian García S.

Active Member
Licensed User
Hello, thanks for your reply.

In GifViewer https://www.b4x.com/android/forum/threads/custom-view-gifviewer.82104/#content class doesn't exist LoadBitmap

B4X:
'v1.20
'Custom View class
Sub Class_Globals
    Private mEventName As String 'ignore
    Private mCallBack As Object 'ignore
    Private mBase As Panel
    Private Const DefaultColorConstant As Int = -984833 'ignore
    Private WorkIndex As Int
    Private BDGravity As Int
    Private bitmaps As List
    Type BitmapAndDelay (bmp As Bitmap, Delay As Int)
End Sub

Public Sub Initialize (Callback As Object, EventName As String)
    mEventName = EventName
    mCallBack = Callback
End Sub

Public Sub DesignerCreateView (Base As Panel, Lbl As Label, Props As Map)
    mBase = Base
    mBase.Visible = False
End Sub

Public Sub SetGif (Dir As String, FileName As String)
    If Dir = File.DirAssets Then
        File.Copy(File.DirAssets, FileName, File.DirInternal, FileName)
        Dir = File.DirInternal
    End If
    Dim path As String = File.Combine(Dir, FileName)
    If Main.GifsCache.IsInitialized = False Then Main.GifsCache.Initialize
    If Main.GifsCache.ContainsKey(path) Then
        bitmaps = Main.GifsCache.Get(path)
    Else
        Dim gd As GifDecoder
        gd.Load(Dir, FileName)
        bitmaps.Initialize
        For i = 0 To gd.FrameCount - 1
            Dim bd As BitmapAndDelay
            bd.Initialize
            bd.bmp = gd.Frame(i)
            bd.Delay = gd.Delay(i)
            bitmaps.Add(bd)
        Next
        Main.GifsCache.Put(path, bitmaps)
    End If

    Dim FirstFrame As BitmapAndDelay = bitmaps.Get(0)
    Dim FirstBmp As Bitmap = FirstFrame.bmp
'    If FirstBmp.Width < mBase.Width Or FirstBmp.Height < mBase.Height Then
'        BDGravity = Gravity.CENTER
'    Else
'        BDGravity = Gravity.FILL
'    End If
  
    BDGravity = Gravity.FILL
  
End Sub

Public Sub Start
    mBase.Visible = True
    WorkIndex = WorkIndex + 1
    ShowImpl(WorkIndex)
End Sub

Public Sub Stop
    mBase.Visible = False
    WorkIndex = WorkIndex + 1
End Sub

Public Sub CallFromResume
    If mBase.Visible Then Start
End Sub

Private Sub ShowImpl(MyWorkIndex As Int)
    Dim FrameIndex As Int = 0
    Do While MyWorkIndex = WorkIndex
        FrameIndex = (FrameIndex + 1) Mod bitmaps.Size
        Dim bdrawable As BitmapDrawable
        Dim bd As BitmapAndDelay = bitmaps.Get(FrameIndex)
        bdrawable.Initialize(bd.bmp)
        bdrawable.Gravity = BDGravity
        mBase.Background = bdrawable
        Sleep(bd.Delay)
    Loop
End Sub

Public Sub GetBase As Panel
    Return mBase
End Sub

I only included:

B4X:
SetApplicationAttribute(android:largeHeap,"true")

But now is blank screen when gif load in my Galaxy S8. I only loaded one time in splash screen.

Thanks
 
Upvote 0

Christian García S.

Active Member
Licensed User
Yes

upload_2018-4-14_17-9-47.png
 
Upvote 0
Top