Android Example LoadBitmapSample -- How Well It Works

I thought I'd provide an interesting look at how well LoadBitmapSample works.

My current Game App that I'm working on generates a Release APK of 10MBytes in size.
The App has the following bitmap sizes [in pixels] (quantity in parentheses):
(1) 1500x750
(1) 1280x1616
(1) 1280x866
(1) 996x129
(1) 857x277
(1) 534x854
(4) 690x282
(4) 282x282
(12) 460x320
(2) 160x160
(2) 150x75
(1) 380x180

[The following is performed in Debug(Legacy) mode to be able to see when the downsampling occurs]:

Prior to using LoadBitmapSample, and without using this line in the Manifest:
SetApplicationAttribute(android:largeHeap,"true"),
I could only change the orientation of my Samsung Galaxy S3 once :eek: before there was extensive downsampling of images due to lack of memory (on the second orientation change). This also caused the GS3 to hang badly enough that I had to remove the battery to reset the device.

By adding the SetApplicationAttribute(android:largeHeap,"true") line to the Manifest, I was able to increase the number of orientation changes to six before downsampling occurred on the 7th o_O orientation change.


I then changed ALL of my bitmap loads to LoadBitmapSample, yielding the following greatly improved results:

Without the "largeHeap" line in the Manifest, I was able to achieve 11 orientation changes before getting an OutOfMemoryError on the 12th :) orientation change.

AND ... by adding the "largeHeap" line to the Manifest, with all bitmap loads using LoadBitmapSample, I was able to increase to 33 ORIENTATION CHANGES before getting an OutOfMemoryError on the 34th ORIENTATION CHANGE.

WOW!! :D:D:D:D:D

Your Apps may give somewhat different results, but if you've shied away from using LoadBitmapSample, this shows how well it helps stave-off memory errors when loading bitmaps.
 
Last edited:

RandomCoder

Well-Known Member
Licensed User
Longtime User
Just out of interest, have you tried saving your bitmaps to process global variables and then reuse these variables. It's sounds very much like you are creating new bitmaps with each orientation change thus gradually chewing up more and more memory until the OOM fault occurs.
 

Guardian17

Active Member
Licensed User
Longtime User
How do you save a bitmap to a variable? I know bitmaps are loaded into Views using file names, but not stored in variables. And the Beginner's Guide says that Views do not get declared as Process_Globals.

This is a sample line of code from my App (pnlLogo is loaded via a Layout):
B4X:
FileName = "MyLogo.png"
pnlLogo.SetBackgroundImage(LoadBitmapSample(File.DirAssets, FileName,pnlLogo.Width,pnlLogo.Height))

How would this be changed to use a Process_Global variable?​
 
Last edited:

Guardian17

Active Member
Licensed User
Longtime User
EXCELLENT!!!!

After moving all of the bitmap definitions to Process_Globals, I re-ran the App...

Without the largeHeap defined in the Manifest, I got the OutOfMemoryError on the 31st orientation change....

But WITH the largeHeap defined in the Manifest, it finally generated the OutOfMemoryError on the 108TH ORIENTATION CHANGE!!!

OUTSTANDING!!!! :D:D:D Thanks, RandomCoder and NJDude!!!
 
Last edited:

thedesolatesoul

Expert
Licensed User
Longtime User
With proper coding, you should actually never get an OOM.
If all of your bitmaps are in process globals, the orientation change should have no effect on them.

On the other hand, did you really sit there rotating the device 108 times and counting that!!!
 

Guardian17

Active Member
Licensed User
Longtime User
Yes. I originally had posted "OVER 100 ORIENTATION CHANGES" as I had counted to 102 on one attempt, but then the Engineer in me said "well how far over 100 would it go?", and I figured SOMEONE may also want to know how far over 100, so I did it again and got to 108.

That being said, are there any other known drains on memory that can help cause out-of-memory errors, because I know I converted ALL of my bitmap loads over to Process_Globals and used LoadBitmapSample for all of them, but yet it still fails after 108 rotations ...?
 

RandomCoder

Well-Known Member
Licensed User
Longtime User
Are you using any canvas objects? Only views are recreated with orientation changes, at least that's my understanding. So all other objects including canvas' s and lists (not to be confused with listview) can be declared as process globals.
 

Guardian17

Active Member
Licensed User
Longtime User
I was using one Canvas object and two Lists in Globals. Tried moving these to Process_Globals. The Lists were OK, but I got an error for the Canvas: Cannot access activity object from sub Process_Globals. So Canvas cannot be a Process_Global, unless there is a different way to declare a Canvas.

But with the Lists now in Process_Globals, and the Canvas back in Globals, (yes, I counted again!), I got the OutOfMemoryError at orientation change 119. I would think 50 orientation changes would suffice for the running of most Apps.

There is one more thing I wanted to do regarding bitmaps which is add an animation sequence when the App is started for the first time that consists of 44 images which are all 534x854 pixels. I was able to declare all of the images programmatically as an array of bitmaps in a loop in Process_Globals, and then my animation Timer_Tick handles the display of those images at the proper times.

Adding these 44 images in Process_Globals brought the number of orientation changes for the main App (after the animation sequence finishes) down to 86 before getting the OutOfMemoryError on the 87th rotation.

Still acceptable!! :D:D:D

Is there a way, after the animation sequence finishes, to purge/delete the array of animation bitmaps so that that memory is freed up?
 

RandomCoder

Well-Known Member
Licensed User
Longtime User
Sorry for misleading you with the Canvas object, I should have checked first. Maybe @wonder could offer his experience here as he's provided many game tutorials and I would imagine he's had his fair share of OOM errors in the past?
 
Top