Android Tutorial Download huge files with HttpUtils2

Discussion in 'Tutorials & Examples' started by Erel, Jun 13, 2013.

Thread Status:
Not open for further replies.
  1. Erel

    Erel Administrator Staff Member Licensed User

    The attached project includes a slightly modified version of HttpUtils2 and a new service named DownloadService. The purpose of DownloadService is to make it simple to download files of any size.

    [​IMG]

    It is very simple to use this service.

    Start a download:
    Code:
    Sub btnDownload_Click
       
    Dim dd As DownloadData
       dd.url = link1 
    '<--- download link
       dd.EventName = "dd"
       dd.Target = Me
       CallSubDelayed2(DownloadService, 
    "StartDownload", dd)
    End Sub
    Handle the events:
    Code:
    Sub dd_Progress(Progress As Long, Total As Long)
       ProgressBar1.Progress = Progress / Total * 
    100
       Label1.Text = 
    NumberFormat(Progress / 102400) & "KB / " & _
          
    NumberFormat(Total / 102400) & "KB"
    End Sub

    Sub dd_Complete(Job As HttpJob)
       
    Log("Job completed: " & Job.Success)
       Job.Release
    End Sub
    Cancel a download:
    Code:
    Sub btnCancel_Click
       CallSubDelayed2(DownloadService, 
    "CancelDownload", link1)
    End Sub
    DownloadService allows you to download multiple files at once and track the progress of each one of them.

    The following libraries are required:
    OkHttp: https://www.b4x.com/android/forum/threads/okhttp-replaces-the-http-library.54723/#content
    StringUtils
    Phone (required in order to acquire a partial lock during the download)
    RandomAccessFile

    As this is a modified version of HttpUtils2 you should not reference HttpUtils2 library. You should instead add the three modules from the attached project. Note that the modified code is in Sub hc_ResponseSuccess.
     

    Attached Files:

    Last edited: Feb 7, 2016
  2. dealsmonkey

    dealsmonkey Active Member Licensed User

    Again, thanks Erel :)
     
  3. yuhong

    yuhong Member Licensed User

    Thanks! It's very good!
     
  4. Jaames

    Jaames Active Member Licensed User

    If use this modules instead of regular HttpUtils2Service and httpjob

    I get this error "java.lang.ClassCastException: java.lang.Object cannot be cast to b4a.example.downloadservice$_jobtag
    "

    Does this mean that we cannot use modules from this example instead of modules from httputils2 example described in this thread?
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    You should change the code in hc_ResponseSuccess (HttpUtils2Service) to:
    Code:
    Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
       
    ' ********** Modified code *************
       Dim cs As CountingOutputStream
       cs.Initialize(
    File.OpenOutput(TempFolder, TaskId, False))
       
    Dim j As HttpJob = TaskIdToJob.Get(TaskId)
       
    If j.Tag Is JobTag Then
          
    Dim jt As JobTag = j.Tag
          jt.CountingStream = cs
          jt.Total = Response.ContentLength
          
    If jt.Data.url = "" Then
             
    Log("Job cancelled before downloaded started")
             cs.Close
          
    End If
       
    End If
       Response.GetAsynchronously(
    "response", cs , _
          
    True, TaskId)
       
    '**************************************
    End Sub
     
  6. Jaames

    Jaames Active Member Licensed User

    Thank you Erel. It is working now.
     
  7. yuhong

    yuhong Member Licensed User

    How Get Download file?

    Code:
    Sub dd_Complete(Successful As Boolean)
        
    Log("Job completed: " & Successful)
    End Sub
    I can't use job,Get download file. help me!

    why not use job in Complete event.
    Code:
    Sub JobDone(job As HttpJob)
       jobs.Remove(job.JobName)
       
    Dim jt As JobTag = job.Tag
       
    If jobs.Size = 0 Then EndTimer
       
    If job.Success Then
          CallSubDelayed3(jt.Data.Target, jt.Data.EventName & 
    "_Progress", _
                jt.CountingStream.Count, jt.Total)
          CallSubDelayed2(jt.Data.Target, jt.Data.EventName & 
    "_Complete", _
                
    True)
       
    Else
          
    Log(job.ErrorMessage)
          CallSubDelayed2(jt.Data.Target, jt.Data.EventName & 
    "_Complete", _
                
    False)
       
    End If
    End Sub
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    I modity the code and OK:

    Code:
    Sub JobDone(job As HttpJob)
       jobs.Remove(job.JobName)
       
    Dim jt As JobTag = job.Tag
       
    If jobs.Size = 0 Then EndTimer
       
    If job.Success Then
          CallSubDelayed3(jt.Data.Target, jt.Data.EventName & 
    "_Progress", _
                jt.CountingStream.Count, jt.Total)
          CallSubDelayed2(jt.Data.Target, jt.Data.EventName & 
    "_Complete", _
                Job)
       
    Else
          
    Log(job.ErrorMessage)
          CallSubDelayed2(jt.Data.Target, jt.Data.EventName & 
    "_Complete", _
                Job)
       
    End If
    End Sub
     
    Last edited: Jun 24, 2013
    koaunglay likes this.
  8. Erel

    Erel Administrator Staff Member Licensed User

    You have two options:
    - Use a different event name for different jobs.
    - Modify the code and add Job.JobName to the event calls.
     
  9. texwillerx

    texwillerx Member Licensed User

    problems with this code

    I used your sample code in my program. Unfortunately, from time to time, the services does not start and callsubdelayed2 module returns immediately.

    1. Do I have to set some parameters in my program to make this code work?

    2. I tried your project, same thing happens. Some times it works, and some time it does not.

    3. Is callsubdelayed2 synchronuos or async?

    4. Is it permissible to change the file name in the service?

    5. When I compile my programs, some time it is installed to the device, some times nothing happens, I have to run it again

    Thanks and regards
     
    leonardoffsilva likes this.
  10. Erel

    Erel Administrator Staff Member Licensed User

    How do you see that the service doesn't start? Are there any messages in the logs?

    CallsubDelayed is asynchronous.
     
  11. texwillerx

    texwillerx Member Licensed User

    I put a breakpoint in dd_Progress, but the program never stops at that point.

    Even I have put a breakpoint in Startdownload procedure, again it didnot stop.

    What about callsubdelayed2? Is it Asynch also?

    If so, how shall I know when the download is complete?

    Thanks
     
  12. texwillerx

    texwillerx Member Licensed User

    Here is my code.

    Nothing is downloaded (DownloadService does not start at all)

    Please help me.

    Thanks

    Sub downloadsystemdb_click
    Dim httpdd As DownloadData
    httpdd.url = ilink
    httpdd.EventName = "httpdd"
    httpdd.Target = Me
    CallSubDelayed2(DownloadService, "StartDownload", httpdd)
    End Sub
    Sub httpdd_Progress(Progress As Long, Total As Long)
    progressbar1.Visible=True
    lblprogress.Visible=True
    progressbar1.Progress = Progress / Total * 100
    lblprogress.Text = NumberFormat(Progress / 1024, 0, 0) & "KB / " & _
    NumberFormat(Total / 1024, 0, 0) & "KB"
    End Sub

    Sub httpdd_Complete(Successful As Boolean)
    progressbar1.Visible=False
    lblprogress.Visible=False
    Log("Job completed: " & Successful)
    End Sub
     
  13. Erel

    Erel Administrator Staff Member Licensed User

    Can you upload your project (File - Export as zip)?
     
  14. texwillerx

    texwillerx Member Licensed User

    Sorry for bothering you.

    After restructuring the code bearing in mind that callsubdelayed is async, everything worked fine.

    Thanks for everything.

    P.S.: I have changed the followings:

    Type DownloadData (url As String, Target As Object, EventName As String,jobname As String,taskid As Int,count As Long,total As Long,retval As Boolean) '*****changed

    Sub JobDone(job As HttpJob)
    jobs.Remove(job.JobName)
    Dim jt As JobTag = job.Tag
    If jobs.Size = 0 Then EndTimer
    If job.Success Then
    jt.Data.count=jt.CountingStream.Count '****added
    jt.Data.total=jt.Total '****added
    jt.Data.retval=True '****added
    CallSubDelayed2(jt.Data.Target, jt.Data.EventName & "_Progress", _
    jt.data) '*****changed
    CallSubDelayed2(jt.Data.Target, jt.Data.EventName & "_Complete", _
    jt.Data) '*****changed
    Else
    jt.Data.retval=False '****added
    Log(job.ErrorMessage)
    CallSubDelayed2(jt.Data.Target, jt.Data.EventName & "_Complete", _
    jt.Data) '*****changed
    End If
    End Sub


    Sub timer1_tick
    For Each job As HttpJob In jobs.Values
    Dim jt As JobTag = job.Tag
    If jt.CountingStream.IsInitialized Then
    jt.Data.count=jt.CountingStream.Count '****added
    jt.Data.total=jt.Total '****added
    jt.Data.retval=True '****added
    CallSub2(jt.Data.Target, jt.Data.EventName & "_Progress", _
    jt.data) '*****changed
    End If
    Next
    End Sub

    Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
    ' ********** Modified code *************
    Dim cs As CountingOutputStream
    cs.Initialize(File.OpenOutput(TempFolder, TaskId, False))
    Dim j As HttpJob = TaskIdToJob.Get(TaskId)
    Dim jt As JobTag = j.Tag
    jt.CountingStream = cs
    jt.Total = Response.ContentLength
    jt.Data.taskid=TaskId '*****changed
    If jt.Data.url = "" Then
    Log("Job cancelled before downloaded started")
    cs.Close
    End If
    Response.GetAsynchronously("response", cs , _
    True, TaskId)
    '**************************************
    End Sub
     
  15. hanyelmehy

    hanyelmehy Active Member Licensed User

    how to get download file
     
  16. Erel

    Erel Administrator Staff Member Licensed User

    Which file?
     
  17. hanyelmehy

    hanyelmehy Active Member Licensed User

    I think file (which was downloaded from url) is saved to TempFolder using TaskId as file name ,how to copy this file to other folder with different name in this sub
    Code:
    Sub dd_Complete(Successful As Boolean)
        
    Log("Job completed: " & Successful)
    End Sub
     
  18. Erel

    Erel Administrator Staff Member Licensed User

    You are correct. It is actually a bug. I've updated the code.

    The correct signature of the Complete event is now:
    Code:
    Sub dd_Complete(Job As HttpJob)
     
    Log("Job completed: " & Job.Success)
     Job.Release
    End Sub
     
  19. grupotgr

    grupotgr Member Licensed User

    where I can find the downloaded file? Thx!
     
  20. Erel

    Erel Administrator Staff Member Licensed User

    The file is downloaded to a temporary folder. You should use File.Copy2 together with Job.GetInputStream to copy the file.
     
    ibra939 and ttsolution like this.
Thread Status:
Not open for further replies.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice