Android Tutorial HttpUtils2 - Web services are now even simpler

Discussion in 'Tutorials & Examples' started by Erel, Jun 24, 2012.

  1. Erel

    Erel Administrator Staff Member Licensed User

    HttpUtils2 was replaced with OkHttpUtils2: https://www.b4x.com/android/forum/threads/okhttp-replaces-the-http-library.54723/
    Both libraries are included in the IDE.


    HttpUtils2 is a small framework that helps with communicating with web services (Http servers).

    HttpUtils2 is an improved version of HttpUtils.

    The advantages of HttpUtils2 over HttpUtils are:
    • Any number of jobs can run at the same time (each job is made of a single task)
    • Simpler to use
    • Simpler to modify
    • Supports credentials
    • GetString2 for encodings other than UTF8
    • Download2 encodes illegal parameters characters (like spaces)

    HttpUtils2 requires Basic4android v2.00 or above.
    It is made of two code modules: HttpUtils2Service and HttpJob (class module).
    The two code modules are included in HttpUtils2 (attached project).
    It depends on the following libraries: Http and StringUtils

    How to use
    - Dim a HttpJob object
    - Initialize the Job and set the module that will handle the JobDone event.
    The JobDone event is raised when a job completes.
    The module can be an Activity, Service or class instance. You can use the Me keyword to reference the current module.
    Note that CallSubDelayed is used to call the event.
    - Call one of the following methods:
    Download, Download2, PostString, PostBytes or PostFile. See HttpJob comments for more information.
    - Handle the JobDone event and call Job.Release when done.
    Note that the completion order may be different than the submission order.

    To send credentials you should set Job.UserName and Job.Password fields before sending the request.

    For example the following code sends three request. Two of the responses will be printed to the logs and the third will be set as the activity background:
    Code:
    Sub Activity_Create(FirstTime As Boolean)
       
    Dim job1, job2, job3 As HttpJob
       job1.Initialize(
    "Job1", Me)

       
    'Send a GET request
       job1.Download2("http://www.basic4ppc.com/print.php", _
          
    Array As String("first key""first value :)""second key""value 2"))

       
    'Send a POST request
       job2.Initialize("Job2", Me)
       job2.PostString(
    "http://www.basic4ppc.com/print.php""first key=first value&key2=value2")

       
    'Send a GET request
       job3.Initialize("Job3", Me)
       job3.Download(
    "http://www.basic4ppc.com/forum/images/categories/android.png")
    End Sub

    Sub JobDone (Job As HttpJob)
       
    Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
       
    If Job.Success = True Then
          
    Select Job.JobName
             
    Case "Job1""Job2"
                
    'print the result to the logs
                Log(Job.GetString)
             
    Case "Job3"
                
    'show the downloaded image
                Activity.SetBackgroundImage(Job.GetBitmap)
          
    End Select
       
    Else
          
    Log("Error: " & Job.ErrorMessage)
          
    ToastMessageShow("Error: " & Job.ErrorMessage, True)
       
    End If
       Job.Release
    End Sub
    This example and an example of downloading several images from Flickr are attached:

    [​IMG]

    Starting from B4A v2.70, HttpUtils2 is included as a library in the IDE.

    Relevant links

    ImageDownloader - Service that makes it simple to efficiently download multiple images. Note that a simpler "FlickrViewer example" is available there.
    DownloadService - Download files of any size with DownloadService. Includes progress monitoring and the ability to cancel a download.
     

    Attached Files:

    Last edited: Feb 28, 2016
    jinyistudio, mobah, hibrid0 and 11 others like this.
  2. mc73

    mc73 Well-Known Member Licensed User

    Great and simpler!
     
  3. salmander

    salmander Active Member Licensed User

    Thank you so much Erel. It will definitely help a lot.....

    Cheers
     
  4. jaminben

    jaminben Member Licensed User

    Super Stuff :D

    Thanks
     
    Last edited: Jun 24, 2012
  5. salmander

    salmander Active Member Licensed User

    Just tried it....and it works like a charm.....cheers Erel.
     
  6. PHB2

    PHB2 Member Licensed User

    Fantastic - thanks Erel
     
  7. PHB2

    PHB2 Member Licensed User

    Do we still need this code Erel:

    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
    I had this in place when I used the original HttpUtils code.
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    No. It is not required as CallSubDelayed takes care of this internally.
     
  9. salmander

    salmander Active Member Licensed User

    Hi Erel,

    I am using HttpUtils2 in PushService to download the data.

    but it is giving me Null Pointer exception. here is the error
    Code:
    httpjob_download2 (java line: 132)

    java.lang.NullPointerException
       at com.home.cafiq.test.httpjob._download2(
    httpjob.java:132)
       at com.home.cafiq.test.pushservice._gettext(pushservice.java:
    218)
       at com.home.cafiq.test.pushservice._messagearrived(pushservice.java:
    454)
       at com.home.cafiq.test.pushservice._service_start(pushservice.java:
    1285)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    511)
       at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    170)
       at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    154)
       at com.home.cafiq.test.pushservice.handleStart(pushservice.java:
    61)
       at com.home.cafiq.test.pushservice.onStartCommand(pushservice.java:
    46)
       at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:
    2359)
       at android.app.ActivityThread.access$
    1900(ActivityThread.java:123)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:
    1210)
       at android.os.Handler.dispatchMessage(Handler.java:
    99)
       at android.os.Looper.loop(Looper.java:
    137)
       at android.app.ActivityThread.main(ActivityThread.java:
    4424)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    784)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    551)
       at dalvik.system.NativeStart.main(Native Method)
    java.lang.RuntimeException: Unable 
    to start service com.home.cafiq.test.pushservice@41119638 with Intent { cmp=com.home.cafiq.test/.pushservice (has extras) }: java.lang.RuntimeException: java.lang.NullPointerException


       at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2376)
       at android.app.ActivityThread.access$1900(ActivityThread.java:123)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4424)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    Any ideas of the cause? and how to rectify it please?

    Edit:
    My push service receives the push notification fine. In my push service, I am downloading additional data from the server using the HttpUtils2 method. But the application is crashing and error logs is giving the above error message.
     
    Last edited: Jun 25, 2012
  10. Erel

    Erel Administrator Staff Member Licensed User

    Can you post the service code?

    Also, you should run your code with the debugger to see the exact error line.
     
  11. salmander

    salmander Active Member Licensed User

    I tried running the code in debugger mode, the app pauses at line 81 of HttpJob of the httputils2 for a second and then the app just crashes. The sub JobDone never gets executed.
    Code:
    ' line 81 of HttpJob module.
       CallSubDelayed2(HttpUtils2Service, "SubmitJob", Me)
    Here is the related service code of PushService (service module).
    Code:
    Sub MessageArrived (Intent As Intent)
       
    Dim From, CollapseKey, Data As String
       
    If Intent.HasExtra("from"Then From = Intent.GetExtra("from")
       
    If Intent.HasExtra("data"Then Data = Intent.GetExtra("data")
       
    If Intent.HasExtra("collapse_key"Then CollapseKey = Intent.GetExtra("collapse_key")

       
    'Here you should handle the new message:
       Log("New message arrived: " & Data)
       
    Log("From: " & From)
       
    Log("CollapseKey: " & CollapseKey)
       
    Log("Data: " & Data)
       
    'ToastMessageShow("New message: " & Data, True)
       
       
    ' Process the message now, calling sub
       getText(Data)
       
    End Sub

    Sub getText(id As String)
       
    Log("getText sub initiated")
       
    'fetch message url
       Dim url As String
       url = 
    "https://" ' https url to get the message details
       'fetchTextHC.Initialize("fetchTextHC")
       'Dim req As HttpRequest
       Log("fetchMessage URL: " & url & "id=" & id)
       
    'req.InitializeGet(url & "id=" & id)
       'fetchTextHC.Execute(req, 1)
       job1.Initialize("getText", Me)
       job1.Download2(url, 
    Array As String("id"id))
       
    End Sub
     
  12. Erel

    Erel Administrator Staff Member Licensed User

    Can you post the error message from the logs?

    Note that the Url is broken. It is missing the host part.
     
  13. salmander

    salmander Active Member Licensed User

    Erel URL is not broken. I removed it as its my company server address.
    Code:
    ** Service (pushservice) Start **


    servicestarted
    New message arrived: 
    322
    From: 
    '<gmail_id hidden>
    CollapseKey: collapse_key1
    Data: 
    322
    getText 
    sub initiated


    fetchMessage URL: <URL>


    httpjob_download2 (B4A line: 
    81)


    CallSubDelayed2(HttpUtils2Service, 
    "SubmitJob", Me)



    java.lang.NullPointerException
       at com.home.cafiq.test.httpjob._download2(
    httpjob.java:180)
       at com.home.cafiq.test.pushservice._gettext(pushservice.java:
    295)
       at com.home.cafiq.test.pushservice._messagearrived(pushservice.java:
    701)
       at com.home.cafiq.test.pushservice._service_start(pushservice.java:
    1981)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    511)
       at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    170)
       at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    154)
       at com.home.cafiq.test.pushservice.handleStart(pushservice.java:
    61)
       at com.home.cafiq.test.pushservice.onStartCommand(pushservice.java:
    46)
       at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:
    2359)
       at android.app.ActivityThread.access$
    1900(ActivityThread.java:123)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:
    1210)
       at android.os.Handler.dispatchMessage(Handler.java:
    99)
       at android.os.Looper.loop(Looper.java:
    137)
       at android.app.ActivityThread.main(ActivityThread.java:
    4424)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    784)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    551)
       at dalvik.system.NativeStart.main(Native Method)
    java.lang.RuntimeException: Unable 
    to start service com.home.cafiq.test.pushservice@411720b8 with Intent { cmp=com.home.cafiq.test/.pushservice (has extras) }: java.lang.RuntimeException: java.lang.NullPointerException
       at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2376)
       at android.app.ActivityThread.access$1900(ActivityThread.java:123)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4424)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
       at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.RuntimeException: java.lang.NullPointerException
       at anywheresoftware.b4a.BA.raiseEvent2(BA.java:199)
       at anywheresoftware.b4a.BA.raiseEvent(BA.java:154)
       at com.home.cafiq.test.pushservice.handleStart(pushservice.java:61)
       at com.home.cafiq.test.pushservice.onStartCommand(pushservice.java:46)
       at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2359)
       ... 10 more
    Caused by: java.lang.NullPointerException
       at com.home.cafiq.test.httpjob._download2(httpjob.java:180)
       at com.home.cafiq.test.pushservice._gettext(pushservice.java:295)
       at com.home.cafiq.test.pushservice._messagearrived(pushservice.java:701)
       at com.home.cafiq.test.pushservice._service_start(pushservice.java:1981)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
       ... 14 more
     
  14. salmander

    salmander Active Member Licensed User

    Any luck Erel?
     
  15. Erel

    Erel Administrator Staff Member Licensed User

    Yes. It is a bug.

    I plan to release v2.02 in a few days that will fix this issue and some others. You can already download v2.01 (considered a beta version) which should fix this issue. It is available in the same link as before. The file name is beta.exe instead of b4a-full.exe.

    I would be happy to hear your results...
     
  16. salmander

    salmander Active Member Licensed User

    Just done a quick test. And it is working now Erel. Thanks again.
     
  17. doomer

    doomer Member Licensed User

    Simple autenticate

    Hi i try to login to a basic login .htaccess file protection

    i set job1.username and password

    how to use the job1.download command with login



    greets doomer
     
  18. Roger Garstang

    Roger Garstang Well-Known Member Licensed User

    Downloaded both of these but haven't really had a chance to use them yet. The example above for POST and GET seem backwards though. The URL Encoded way you send the POST would work better for GET and an Array or Map way would work better for POST. POST would work best sent as multipart/form-data instead of url encoded like GET then you can send binary files, images, etc.
     
  19. Erel

    Erel Administrator Staff Member Licensed User

    @doomer,
    You should just set the UserName and Password:
    Code:
    job3.Initialize("Job3", Me)
    job3.Username = 
    "xxx"
    job3.Password = 
    "yyy"
    job3.Download(
    "http://www.example.com")
    @Roger, only the GET parameters need to be url encoded. It is a good idea to add an option for multipart/form-data.
     
    luke2012, GMan and LaryLee like this.
  20. doomer

    doomer Member Licensed User

    it works next question: How to save file ?

    when i download a file wit

    jonb1.dowload(filurl)

    how to save

    this is done with httputil the old one

    File.Copy2(httputil.GetInputStream(FileUrl),File.OpenOutput(File.DirDefaultExternal,"Test.ini",False))


    how to do that with httpjob.

    greets

    Doomer
     
Loading...