Android Question [Solved] OutOfMemoryError with canvas

angel_

Well-Known Member
Licensed User
Longtime User
On some devices (low range) I have this error.

B4X: Copy
java.lang.OutOfMemoryError: Failed to allocate a 182088012 byte allocation with 4194304 free bytes and 64MB until OOM
    at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
    at android.graphics.Bitmap.nativeCreate(Native Method)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:812)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:789)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:756)
    at anywheresoftware.b4a.objects.drawable.CanvasWrapper.Initialize(CanvasWrapper.java:81)
    at anywheresoftware.b4a.objects.B4XCanvas.Initialize(B4XCanvas.java:54)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:777)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:354)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:197)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:4900)
    at android.view.View$PerformClick.run(View.java:20381)
    at android.os.Handler.handleCallback(Handler.java:815)
    at android.os.Handler.dispatchMessage(Handler.java:104)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5877)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)

Code: Copy
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
  
    Panel1.Height = 6 * 100%y
    Panel1.Width = 6 * 100%x
End Sub

Sub Button1_Click
    Dim cvsPnl As B4XCanvas
    cvsPnl.Initialize(Panel1)
   'doing something
End Sub

Is there a way to avoid this error?
 

Attachments

i don't think there is a way except decreasing the height and the width values :

may i ask why are you doing this ? :


it may work on some devices because they have more memory or less dpi but this is a very wrong approach my friend
I have a kind of canvas where I place items and I want it to be large enough
 
Upvote 0
the problem is not the panel but the canvas.

Opening such a large canvas even on ScrollView2D would generate an out of memory error in some devices.

Try Using LargeHeap
 
Upvote 0
I suggest dividing the items into several canvases or better memorized as files and recalling them when needed
 
Upvote 0
Upvote 0
the problem is not the panel but the canvas.

Opening such a large canvas even on ScrollView2D would generate an out of memory error in some devices.

Try Using LargeHeap
I'll try it

Is it possible to know the maximum size that the device will allow? or an approximate value
 
Upvote 0
I'll try it

Is it possible to know the maximum size that the device will allow? or an approximate value
I do not know
 
Upvote 0
I had major problems with Canvas size when targeting SDKs greater than 13 where the maximum available Canvas size seems to be dramatically smaller. As I wanted to display large images, and could no longer do so after SDK 13, I created ScaleImageView, although this is probably of no use to you in your application.
 
Upvote 0
No.

Creating such a large canvas is a sure way to get out of memory errors. Can you post a screenshot of the app?
This panel with large dimensions is a DraggableView with a screenshot you will not appreciate. I think the best option is resize the panel.

It seems the best option is to resize the panel at runtime based on the elements it contains, it is true?
 
Upvote 0
Upvote 0
But I still have the same problem, the panel is too big and when I want to snapshot it gives an error
 
Upvote 0
You might be able to use ScaleImageView. Either the user, or your program without user intervention, could zoom and position your large image and the OnDraw event provides a Canvas object whose Bitmap property you could probably use to get the displayed portion of the image. You could probably not make it visible or hide it off screen if you don't want the user to see it.

I know it's not cross platform but I guess you could do something different in B4J as it JavaFX can probably display much larger images than Android.

Thre's lots of probables because I haven't tried it!
 
Upvote 0
In the end, instead of getting the image of the large panel and cropped, I opted to create a new panel with the dimensions of the content (smaller dimensions) of the large panel and then get the image of the latter panel then I delete this panel
 
Upvote 0
Back
Top