Android Question Downsampling image due to lack of memory

catyinwong

Active Member
Licensed User
The error appears whenever I have switched between pages of the app for about 5-6 times.. I have searched the forum but there seems to be no solution to solve the problem??
 

sorex

Expert
Licensed User
it depends on how you wrote your app and how it is working.

without knowing that it's hard to give any advice.
 

catyinwong

Active Member
Licensed User
It happens whenever it needs to download images... Like 3 to 4 in a module.. It seems likes the memory doesn't release even if I finish the activity?
 

KZero

Active Member
Licensed User
how you load your bitmaps ? post the relevant part of code if possible
-try using LoadBitmapSample if you loading high res. images
-try recycling the bitmap if its not in use
B4X:
    Try
    Dim Obj1 As Reflector
    Obj1.Target = Thebitmap
    Obj1.RunMethod ("recycle")
    Catch
    log("Error Recycling Bitmap")
    End Try
-call Activity.Finish in Activity_Pause
 

catyinwong

Active Member
Licensed User
how you load your bitmaps ? post the relevant part of code if possible
-try using LoadBitmapSample if you loading high res. images
-try recycling the bitmap if its not in use
B4X:
    Try
    Dim Obj1 As Reflector
    Obj1.Target = Thebitmap
    Obj1.RunMethod ("recycle")
    Catch
    log("Error Recycling Bitmap")
    End Try
-call Activity.Finish in Activity_Pause

B4X:
 For inx = 0 To m.size - 1  'm is the map where I put all the picture address
 Dim picv As String = m.Get(inx) 
 p.Initialize("") 
 clv.add(p,100%x + 5,link) 'clv is the custom list view
 p.LoadLayout("ImageView")
 If picv <> Null Then m2.Put(imageview1,picv) 'I use the image downloader to put the image into the imageview
 Next
Where should I put the codes for recycling the bitmap???
I try calling activity.finish in Activity_pause, but it didn't help. The memory used up as fast as before.
 

KZero

Active Member
Licensed User
B4X:
For inx = 0 To m.size - 1  'm is the map where I put all the picture address
Dim picv As String = m.Get(inx)
p.Initialize("")
clv.add(p,100%x + 5,link) 'clv is the custom list view
p.LoadLayout("ImageView")
If picv <> Null Then m2.Put(imageview1,picv) 'I use the image downloader to put the image into the imageview
Next
Where should I put the codes for recycling the bitmap???
I try calling activity.finish in Activity_pause, but it didn't help. The memory used up as fast as before.
what the bitmap resolutions and how many bitmaps loaded
you can recycle the bitmap if its not used anymore but i think u always using it

-try to load the bitmaps 1 time and store them in process global variables instead of reloading each time the activity start

if you loading large bitmaps or high number try adding this line to your manifest editor
B4X:
SetApplicationAttribute(android:largeHeap, "true")
its not supported on android 2.x
 

catyinwong

Active Member
Licensed User
what the bitmap resolutions and how many bitmaps loaded
you can recycle the bitmap if its not used anymore but i think u always using it

-try to load the bitmaps 1 time and store them in process global variables instead of reloading each time the activity start

if you loading large bitmaps or high number try adding this line to your manifest editor
B4X:
SetApplicationAttribute(android:largeHeap, "true")
its not supported on android 2.x
Some examples:
http://static.wixstatic.com/media/4...ng_srz_p_519_460_75_22_0.50_1.20_0.00_png_srz
http://static.wixstatic.com/media/4...pg_srz_p_252_252_75_22_0.50_1.20_0.00_jpg_srz
Not sure about the resolutions

The major problem I think is that the memory doesn't clear up after the close the module (end the activity) because at first the pictures are loaded fine.. I try to close and open and close and open the module, then the memory is used up for about 5-6 times.. Actually they should not store anything after I close them.. Otherwise the problem will never be solved and the memory will eventually used up anyway.. How to clear the memory after the module is close??
 

KZero

Active Member
Licensed User
the system will automatically release the activity memory if its not in use but its not immediately.
the images are big if you loading them into small imageviews in the CLV you should use LoadBitmapSample it will help to decrease the memory usage
if this images is frequently used in your application i recommend to load them one time and store them in process global variables to stop memory increasing each time you load them
 

catyinwong

Active Member
Licensed User
the system will automatically release the activity memory if its not in use but its not immediately.
the images are big if you loading them into small imageviews in the CLV you should use LoadBitmapSample it will help to decrease the memory usage
if this images is frequently used in your application i recommend to load them one time and store them in process global variables to stop memory increasing each time you load them
How do I load a web image through loadbitmapsample??
 

KZero

Active Member
Licensed User
How do I load a web image through loadbitmapsample??
by saving the bitmap to file (i think you should save it to DirInternalCache instead of re-downloading each time) or try this code to scale the bitmap without saving it

B4X:
Sub CreateScaledBitmap(Original As Bitmap, Width As Int, Height As Int) As Bitmap
    Dim r As Reflector
    Dim Filter As Boolean =False
    Dim b As Bitmap
    b = r.RunStaticMethod("android.graphics.Bitmap", "createScaledBitmap", _
        Array As Object(Original, Width, Height, Filter), _
        Array As String("android.graphics.Bitmap", "java.lang.int", "java.lang.int", "java.lang.boolean"))
    Return b
End Sub
 

catyinwong

Active Member
Licensed User
by saving the bitmap to file (i think you should save it to DirInternalCache instead of re-downloading each time) or try this code to scale the bitmap without saving it

B4X:
Sub CreateScaledBitmap(Original As Bitmap, Width As Int, Height As Int) As Bitmap
    Dim r As Reflector
    Dim Filter As Boolean =False
    Dim b As Bitmap
    b = r.RunStaticMethod("android.graphics.Bitmap", "createScaledBitmap", _
        Array As Object(Original, Width, Height, Filter), _
        Array As String("android.graphics.Bitmap", "java.lang.int", "java.lang.int", "java.lang.boolean"))
    Return b
End Sub
I am not sure about how to use this code... like this??

B4X:
Dim pic as string 'as the picture address
Dim Imageview1 as imageview 'as the image view to show the picture
Imageview1.bitmap = CreateScaledBitmap(pic,Imageview1.width,Imageview1.height)
 

KZero

Active Member
Licensed User
I am not sure about how to use this code... like this??

B4X:
Dim pic as string 'as the picture address
Dim Imageview1 as imageview 'as the image view to show the picture
Imageview1.bitmap = CreateScaledBitmap(pic,Imageview1.width,Imageview1.height)
this function to resize the Bitmap not to download it so you need to pass the downloaded Bitmap not the picture address

i'm not familiar with the used Image downloader and how to get the Bitmap using it
 

Erel

Administrator
Staff member
Licensed User
1. Remove the reference to HttpUtils2 library.
2. Add HttpUtils2 modules instead.
3. Add this sub to HttpJob:
B4X:
'Returns the response as a bitmap loaded with LoadBitmapSample.
Public Sub GetBitmapSample(Width As Int, Height As Int) As Bitmap
   Return LoadBitmapSample(HttpUtils2Service.TempFolder, taskId, Width, Height)
End Sub
4. Modify ImageDownloader to use GetBitmapSample instead of GetBitmap.
 

catyinwong

Active Member
Licensed User
1. Remove the reference to HttpUtils2 library.
2. Add HttpUtils2 modules instead.
3. Add this sub to HttpJob:
B4X:
'Returns the response as a bitmap loaded with LoadBitmapSample.
Public Sub GetBitmapSample(Width As Int, Height As Int) As Bitmap
   Return LoadBitmapSample(HttpUtils2Service.TempFolder, taskId, Width, Height)
End Sub
4. Modify ImageDownloader to use GetBitmapSample instead of GetBitmap.
In the ImageDownloader_GetBitmapSample, what should I put as the width and height parameter?? Shouldn't it be flexible according to the imageview or the web image??
 

catyinwong

Active Member
Licensed User
You will need to implement such a solution. You will need to find the correct ImageView and get its size. However you can also use an approximated size that will be good for all images.
How should I modify the ImageDownloader to determine whether the same images have already been downloaded and reload the previously downloaded image so that the downloading won't repeat and waste the memory???
 

Troberg

Well-Known Member
Licensed User
How should I modify the ImageDownloader to determine whether the same images have already been downloaded and reload the previously downloaded image so that the downloading won't repeat and waste the memory???
You'll have to create some kind of mechanism to remember what images you have downloaded. There isn't anyone made for you. It's not that hard to do, so just give it a try.
 

catyinwong

Active Member
Licensed User
You'll have to create some kind of mechanism to remember what images you have downloaded. There isn't anyone made for you. It's not that hard to do, so just give it a try.
Let me put it this way.. For the ImageDownloader, anyone knows where the images are stored?? Is it in a temp file, a map or a list form?? Because I need to figure out how it works before I can try to modify it...
 
Top