Android Question Out of memory crash,When load more than 70 images

hi everyone , my problem When i Try to load more items to custom list view with image url in beginning work good, but when i load more than 70 cards with images I got this error

Downsampling image due to lack of memory.
this is my code ::
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("cards")
    ProgressDialogShow2("تحميل البيانات , يرجى الانتظار ...",False)
    job1
End Sub

Sub job1()
    Log("Entering job1")
    Dim http1 As HttpJob
    http1.Initialize("job1", Me)
    http1.PostString(ServerUrl, "Select   REPLACE('http://www.aqaratyemen.com/Uploads/'+ i_images, ' ', '%20') as i_image  , num,id,aqar_for + ' ' + N_name as  N_name , Format(price_yr , '##,##0') as price_yr ,omla,city + ' | ' + Location as Location, SUBSTRING(other_info, 1, 130) +'....' as  other_info,date_post, aqar_for,s_space_lbn,phone_waset,Office_phone,sold,gabel,city FROM   aqarat  where show_dont='True'   order  by num Desc")
    wait for (http1) JobDone(http1 As HttpJob)
    If http1.Success Then
        Log("job1 success")
        response=http1.GetString
        parser.Initialize(response)
        Dim rows As List
        rows = parser.NextArray
      
        'work with result
        'rows is a List. Each item is a Map with the columns names as keys and the db values as the values.
        'For i = 0 To rows.Size - 1
        Dim currentNumberOfItems As Int  = CLV1.GetSize
        For i = currentNumberOfItems   To (currentNumberOfItems + 19)
            m = rows.Get(i)
            Dim num As String=m.Get("num")
            Dim id As String=m.Get("id")
            Dim N_name As String=m.Get("N_name")
            Dim price_yr As String=m.Get("price_yr")
            Dim omla As String=m.Get("omla")
            Dim Location As String=m.Get("Location")
            Dim other_info As String=m.Get("other_info")
            Dim date_post As String=m.Get("date_post")
            'Dim aqar_for As String=res.GetString2("aqar_for")
            'Dim s_space_lbn As String=res.GetString2("s_space_lbn")
            Dim phone_waset As String=m.Get("phone_waset")
            'Dim Mtmez As String=res.GetString2("Mtmez")
            Dim Office_phone As String=m.Get("Office_phone")
            Dim sold As String=m.Get("sold")
            'Dim i_imagexx As String=m.Get("i_image")
            'Dim city As String=res.GetString2("city")
  
  
            CLV1.Add(CreateItem(CLV1.AsView.Width,num,id,N_name,price_yr,omla,Location,other_info,date_post,phone_waset,Office_phone,sold),"")
            ' for imges
            Try
                If  m.Get("i_image") = Null Then
                    DownloadImage("http://www.aqaratyemen.com/images/noimageavailable.png",ImageView1)
                Else
                    DownloadImage(m.Get("i_image"),ImageView1)
                End If
            Catch
                Log(LastException)
            End Try
        Next
        ProgressDialogHide
    Else
        Log("job1 failure")
      
    End If
    Log("Exiting job1")
End Sub

Sub DownloadImage(Link As String, iv As ImageView)
    Dim j As HttpJob
    j.Initialize("", Me)
    j.Download(Link)
    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        iv.Bitmap = j.GetBitmap
    End If

    j.Release
End Sub

Private Sub CreateItem(Width As Int,num As String,id As String ,N_name As String,price_yr As String,omla As String,Location As String,other_info As String,date_post As String,phone_waset As String,Office_phone As String,sold As String) As Panel
    Dim p As B4XView = xui.CreatePanel("")
    Dim height As Int = 190dip
    'If GetDeviceLayoutValues.ApproximateScreenSize < 4.5 Then height = 180dip
  
  
    p.SetLayoutAnimated(0, 0, 0, Width, height)
    p.LoadLayout("card_items")
  
    lbl_num.Text =num
    lblTitle.Text =N_name
    Lbl_price.Text=price_yr
    lbl_omla.Text=omla
    lbl_loction.Text =Location
    Lblinfo.Text =other_info
    lbl_date.Text =TimeAgo(date_post)
    lbl_ph_wset.Text =phone_waset
    lbl_ph_office.Text =Office_phone
    lbl_sold.Text =sold
  

    lblTitle.Typeface=mada
    lbl_loction.Typeface=mada
    lbl_omla.Typeface=mada
    Lbl_price.Typeface=mada
    Lblinfo.Typeface=mada
    lbl_date.Typeface=mada
    Button1.Typeface=mada
  
    lblTitle.Gravity=Gravity.RIGHT
    lbl_loction.Gravity=Gravity.RIGHT
    lbl_omla.Gravity=Gravity.RIGHT
    Lbl_price.Gravity=Gravity.RIGHT
    Lblinfo.Gravity=Gravity.RIGHT
    lbl_date.Gravity=Gravity.RIGHT
  
    Return p
End Sub


Sub SetColorStateList(Btn As Label,Pressed As Int,Enabled As Int)
    Dim States(2,1) As Int
    States(0,0) = 16842919    'Pressed
    States(1,0) = 16842910    'Enabled
    Dim CSL As JavaObject
    CSL.InitializeNewInstance("android.content.res.ColorStateList",Array(States,Array As Int(Pressed, Enabled)))
    Dim B1 As JavaObject = Btn
    B1.RunMethod("setTextColor",Array As Object(CSL))
End Sub
 
Last edited:
and I use this code when I load more items :
B4X:
Sub CLV1_ReachEnd
    Try
        ProgressDialogShow("Load More")
        Log("Refresh")
        job2
    Catch
        Log(LastException)
    End Try

End Sub
Sub job2()
    Log("Entering job2")
    Dim http2 As HttpJob
    http2.Initialize("Job2", Me)
    http2.PostString(ServerUrl, "Select   REPLACE('http://www.aqaratyemen.com/Uploads/'+ i_images, ' ', '%20') as i_image  , num,id,aqar_for + ' ' + N_name as  N_name , Format(price_yr , '##,##0') as price_yr ,omla,city + ' | ' + Location as Location, SUBSTRING(other_info, 1, 130) +'....' as  other_info,date_post, aqar_for,s_space_lbn,phone_waset,Office_phone,sold,gabel,city FROM   aqarat  where show_dont='True'   order  by num Desc")

    wait for (http2) JobDone(http2 As HttpJob)
    If http2.Success Then
        Log("job2 success")
        response=http2.GetString
        parser.Initialize(response)
        Dim rows As List
        rows = parser.NextArray
        Dim currentNumberOfItems As Int  = CLV1.GetSize
        For i = currentNumberOfItems   To (currentNumberOfItems + 19)
            '    Log("Rows #" & i)
            'Dim m As Map
            m = rows.Get(i)
            Dim num As String=m.Get("num")
            Dim id As String=m.Get("id")
            Dim N_name As String=m.Get("N_name")
            Dim price_yr As String=m.Get("price_yr")
            Dim omla As String=m.Get("omla")
            Dim Location As String=m.Get("Location")
            Dim other_info As String=m.Get("other_info")
            Dim date_post As String=m.Get("date_post")
            Dim phone_waset As String=m.Get("phone_waset")
            Dim Office_phone As String=m.Get("Office_phone")
            Dim sold As String=m.Get("sold")

            CLV1.Add(CreateItem2(CLV1.AsView.Width,num,id,N_name,price_yr,omla,Location,other_info,date_post,phone_waset,Office_phone,sold),"")
            ' Fore download imges from url
            Try
                If  m.Get("i_image") = Null Then
                    DownloadImage("http://www.aqaratyemen.com/images/noimageavailable.png",ImageView1)
                Else
                    DownloadImage(m.Get("i_image"),ImageView1)
                End If
            Catch
                Log(LastException)
            End Try
        
        Next
        ProgressDialogHide
        
    Else
        Log("job2 failure")
    End If
    Log("Exiting job2")
End Sub



Private Sub CreateItem2(Width As Int,num As String,id As String ,N_name As String,price_yr As String,omla As String,Location As String,other_info As String,date_post As String,phone_waset As String,Office_phone As String,sold As String) As Panel
    Dim p As B4XView = xui.CreatePanel("")
    Dim height As Int = 190dip
    'If GetDeviceLayoutValues.ApproximateScreenSize < 4.5 Then height = 180dip
    p.SetLayoutAnimated(0, 0, 0, Width, height)
    p.LoadLayout("card_items")
    
    lbl_num.Text =num
    lblTitle.Text =N_name
    Lbl_price.Text=price_yr
    lbl_omla.Text=omla
    lbl_loction.Text =Location
    Lblinfo.Text =other_info
    lbl_date.Text =TimeAgo(date_post)
    lbl_ph_wset.Text =phone_waset
    lbl_ph_office.Text =Office_phone
    lbl_sold.Text =sold
    
    lblTitle.Typeface=mada
    lbl_loction.Typeface=mada
    lbl_omla.Typeface=mada
    Lbl_price.Typeface=mada
    Lblinfo.Typeface=mada
    lbl_date.Typeface=mada
    Button1.Typeface=mada
    
    lblTitle.Gravity=Gravity.RIGHT
    lbl_loction.Gravity=Gravity.RIGHT
    lbl_omla.Gravity=Gravity.RIGHT
    Lbl_price.Gravity=Gravity.RIGHT
    Lblinfo.Gravity=Gravity.RIGHT
    lbl_date.Gravity=Gravity.RIGHT
    
    Return p
End Sub
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
it's a phone; how much do you really think it's going to hold before it explodes?

your code::
   If j.Success Then
        iv.Bitmap = j.GetBitmap    ' <----- [U]YOU'RE ASSIGNING WITHOUT FIRST RESIZING DOWN OR SAMPLING[/U]
    End If
re: your DownloadImage() sub, unless i'm misreading your code, i don't see where you're sampling. you just download and assign the downloaded bitmap to the imageview without any resizing. you might want to start there and hope android's garbage collection comes into play.
there is no way to avoid downloading the full size image, but there is no law requiring you to assign that full size image to an imageview without first resizing or sampling it.

when you call "j.release", that frees a temp file created by okhttp when it downloads the image. you need to hope that resizing frees up more memory. in other words: when you resize downward, you end up with a big image (before) and a small one (after). you can hope that android is smart enough to garbage collect the before image since it is no longer used. in any case, start with sampling or resizing and see if you can load more images before exploding.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
the thing with lazy loading, i believe, involves all the resources being on the device already. since only a certain number can fit on the screen at a time, you basically only have to load that number at once. the more images you try to show at once, the more demand on the system. as the user scrolls through the view, images already seen (eg, at the top) are replaced (at the bottom) by more images. since all the images would be on the device, the system could load into and unload from the scrolling view very quickly. in this case, the images are being loaded from an external source. once the user scrolls past the already downloaded images, there is no guarantee that the next group to be lazy loaded are available. technically, i believe the only way lazy loading might work in this case would be to download the images in a background service and write them to disk. then try lazy loading in the foreground and hope the images are there when the user scrolls through the view. sampling the saved images for display would certainly save memory, but i think the real issue is guaranteeing the user doesn't see a blank view because she has scrolled past the last lazy loaded image and there are no more images available for the moment.
 
Upvote 0
Top