B4A Tutorial HttpUtils - Android web services are now simple!

Discussion in 'Tutorials & Examples' started by Erel, May 15, 2011.

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

    Erel Administrator Staff Member Licensed User

    HttpUtils2 is now available. HttpUtils2 is an improved version and is recommended for new projects.

    HttpUtils is made of a code module and a service module. These two modules make it very simple to download online resources and upload data.

    The advantages of using HttpUtils are:
    • Much simpler than working with HttpClient directly.
    • Handles parallel calls efficiently and correctly (protects from RejectedExecutionException exceptions).
    • Downloads are not affected by the activity life cycle.
    Using HttpUtils

    A simple example of downloading a page and returning the page as string:
    Code:
    Sub Globals
     
    Dim b4a As String
     b4a = 
    "http://www.basic4ppc.com"
    End Sub

    Sub Activity_Create (FirstTime As Boolean)
     HttpUtils.CallbackActivity = 
    "Main" 'Current activity name.
     HttpUtils.CallbackJobDoneSub = "JobDone"
     HttpUtils.Download(
    "Job1", b4a)
    End Sub

    Sub JobDone (Job As String)
     
    Dim s As String
     
    If HttpUtils.IsSuccess(b4a) Then
      s = HttpUtils.GetString(b4a)
     
    End If
    End Sub
    First we configure the callback subs. Then we call HttpUtils.Download or HttpUtils.DownloadList. These calls submit a job request to HttpUtils.
    A job is made of one or more links.
    HttpUtils raises two types of events while processing a job. The UrlDone event is raised for each successful download with the downloaded url and the JobDone event is raised when the whole job finishes.
    You cannot submit a new job while a current job is running (though a job can contain many links).

    We have three ways to access a downloaded resource:
    • HttpUtils.GetString(Url As String) - Returns the resource as string
    • HttpUtils.GetBitmap(Url As String) - Returns the resource as bitmap
    • HttpUtils.GetInputStream(Url As String) - Returns an InputStream which allows you to manually read the downloaded resource.
    These three methods should only be called after the job is done or inside the UrlDone event sub (for that specific Url).
    After downloading a resource the Url serves as the key for that resource.

    Inside JobDone event sub you should call HttpUtils.IsSuccess before accessing any Url as it is possible that some or all of the downloads have failed. This is not necessary in UrlDone event as UrlDone is called for each successful download.

    Second example:
    In this example we first download an image and set it as the activity background. Then we download another 6 Urls and print the last one as string. The code for this example is attached.
    Code:
    Sub Process_Globals
        
    Dim ImageUrl As String
        ImageUrl = 
    "http://www.basic4ppc.com/android/images/logo2.png"
        
    Dim Job2Links As List
    End Sub

    Sub Globals

    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        HttpUtils.CallbackActivity = 
    "Main"
        HttpUtils.CallbackJobDoneSub = 
    "JobDone"
        HttpUtils.CallbackUrlDoneSub = 
    "UrlDone"
        Job2Links.Initialize
        Job2Links.AddAll(
    Array As String( _ 
            
    "http://www.google.com""http://www.yahoo.com", _
            
    "http://www.bing.com""http://www.cnn.com", _
            
    "http://www.twitter.com""http://www.facebook.com"))
        
        HttpUtils.Download(
    "Job1", ImageUrl)
    End Sub

    Sub Activity_Resume
        
    'Check whether a job has finished while the activity was paused.
        If HttpUtils.Complete = True Then JobDone(HttpUtils.Job)
    End Sub
    Sub UrlDone(Url As String)
        
    Log(Url & " done")
    End Sub
    Sub JobDone (Job As String)
        
    Select Job
            
    Case "Job1"
                
    If HttpUtils.IsSuccess(ImageUrl) Then 
                    
    Dim b As Bitmap
                    b = HttpUtils.GetBitmap(ImageUrl)
                    Activity.SetBackgroundImage(b)
                
    End If
                
    'Start the second job
                HttpUtils.DownloadList("Job2", Job2Links)
            
    Case "Job2"
                
    For i = 0 To HttpUtils.Tasks.Size - 1
                    link = HttpUtils.Tasks.Get(i)
                    
    Log(link & ": success=" & HttpUtils.IsSuccess(link))
                
    Next
                
    If HttpUtils.IsSuccess("http://www.google.com"Then
                    
    Log(HttpUtils.GetString("http://www.google.com"))
                
    End If
        
    End Select
        HttpUtils.Complete = 
    False 'Turn off the complete flag so we won't handle it again if the activity is resumed.
    End Sub
    What happens when the user presses on the Home key during a download?
    The download will complete successfully (we are using a service for this).
    However your activity will be paused and the UrlDone and JobDone events will not fire.

    When our activity is resumed we should check if we missed anything. This is done with this code:
    Code:
    Sub Activity_Resume
        
    'Check whether a job has finished while the activity was paused.
        If HttpUtils.Complete = True Then JobDone(HttpUtils.Job)
    End Sub
    We are calling JobDone ourselves if needed.
    In Sub JobDone we reset the Complete flag so we know that this job was handled.
    UrlDone event should be considered a "nice to have" feature. Your code should be prepared to handle the case where some UrlDone events were missed due to the activity being paused.

    The FlickrViewer example was rewritten and the attached code uses this module.
    In this example we first go to the "main" page. In this page we find 9 links to 9 images. We submit a second job with all these links.

    We show each image as soon as it is ready by using the UrlDone event.
    In JobDone we check if all Urls were handled. We can miss some of these events if the activity was paused during download.

    [​IMG]


    HttpUtils, similar to DBUtils, aims to simplify common tasks that many developers face. The code is available for you. So changes can be made as needed.

    Updates:

    V1.04 - The service is now destroyed when it is no longer needed and recreated when needed again. This version also fixes a bug that caused the application to crash if the service was started after the process was killed.

    V1.02 - PostString, PostBytes and PostFile methods added to HttpUtils.
    These methods make it easy to post data to a web service (using http POST method).
    The behavior of these methods is similar to Download and DownloadList. JobDone event is raised after the response from the server is read.

    The latest version (v1.04) is included in HttpUtilsExample.
     

    Attached Files:

    bluedude likes this.
  2. Vidar

    Vidar Member Licensed User

    I love you :D

    Just been playing around with the httpclient.

    Thanks for this :)
     
    navidm likes this.
  3. Inman

    Inman Well-Known Member Licensed User

    Fantastic!

    Does this mean even if I send a relatively large list of urls (say 50) to HttpUtils, it will handle the queue correctly and download completely while avoiding RejectedExecutionException completely?
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    Yes.
     
  5. ietv

    ietv Member Licensed User

    I get an error with this:

    java.lang.RuntimeException: Error loading Bitmap.

    Debugger finds it in HttpUtilsService at

    b = LoadBitmap(HttpUtilsService.TempFolder, SuccessfulUrls.Get(URL))

    For what it's worth, I got it to run last night on a different emulator, but when I tried to modify the url to a different page, I got an array out of bounds error (I think, I'm going by memory).
     
  6. Cynikal

    Cynikal Member Licensed User

    I am confused, is this a library?
     
  7. Vidar

    Vidar Member Licensed User

    @Cynikal

    No, these are modules, which include some kind of helper-functions. You can add them to your project with: "Project --> Add existing module" and use it, like Erel has described it in his example
     
  8. Kiffi

    Kiffi Active Member Licensed User

    Hello Erel,

    works like a charm. Thanks a lot! :sign0098:

    Greetings ... Kiffi
     
  9. Erel

    Erel Administrator Staff Member Licensed User

    This can happen if the image file is corrupted or it is not an image file at all. It can also happen when you try to load a large bitmap and there is not enough memory.
     
  10. Cynikal

    Cynikal Member Licensed User

    Getting an error when trying to use the 'GetString'

    An error has occured in sub: httputils_issuccess (java line: 113)
    java.lang.RuntimeException: Object should first be initialized (Map)
     
  11. Erel

    Erel Administrator Staff Member Licensed User

    You should first call Download or DownloadList. Then wait for JobDone or UrlDone events.
     
  12. NeoTechni

    NeoTechni Well-Known Member Licensed User

    Minor alteration:

    In HttpUtilsService, inside Sub ProcessNextTask
    Line: 41
    Replace: req.InitializeGet(link)
    With: req.InitializeGet(link.Replace(" ", "%20"))

    This stops an error when the URL has a space in it.
     
  13. Erel

    Erel Administrator Staff Member Licensed User

    HttpUtils v1.02 posted in first post. v1.02 adds three new methods: PostString, PostFile and PostBytes. These methods make it easy to send Http POST requests.
     
  14. bluedude

    bluedude Well-Known Member Licensed User

    That is pretty amazing, now it would be nice to have something to post image and attached data for for example: Twitpic - Share photos and videos on Twitter

    Together with the AdvancedCamera stuff that would make a cool combination.
     
  15. Erel

    Erel Administrator Staff Member Licensed User

  16. bluedude

    bluedude Well-Known Member Licensed User

    Ok, will try to get this into the httputils myself.
     
  17. rajaramcomputers

    rajaramcomputers Member Licensed User

  18. Erel

    Erel Administrator Staff Member Licensed User

    The latest version is already included in the IDE (go to the Libraries tab at the right pane).

    Edit: Just saw your nice post in the Beginners tips thread. Thank you :)
     
  19. xalion

    xalion Member Licensed User

    I use result=HttpUtils.GetString(loginurl)
    and my result is chinese, so result is can't readble.
    when I use old response.GetString("UTF8"), it works ok.
    can you check it?
     
  20. Erel

    Erel Administrator Staff Member Licensed User

    The problem is that the response is not encoded in UTF8.
    When you call Response.GetString the encoding parameter is only used if there is no encoding information in the response. In your case there is so the call response.GetString("UTF8") worked correctly.

    You should use HttpUtils.GetInputStream together with a TextReader that is initialized with the correct encoding.
     
Thread Status:
Not open for further replies.

Share This Page

Loading...