Android Tutorial HttpUtils2 - Web services are now even simpler

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:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Dim job1, job2, job3 As HttpJob
   job1.Initialize("Job1", Me)

   'Send a GET request
   job1.Download2("http://www.b4x.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.b4x.com/print.php", "first key=first value&key2=value2")

   'Send a GET request
   job3.Initialize("Job3", Me)
   job3.Download("http://www.b4x.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:

flickr_viewer1.png


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.
 

Attachments

  • FlickrViewer.zip
    10.7 KB · Views: 9,007
  • HttpUtils2.zip
    8.5 KB · Views: 11,272
Last edited:

jaminben

Member
Licensed User
Longtime User
Hi,

I'm trying to use Download2 to deal with illegal parameter characters like spaces but don't seem to be having any luck.

My code looks like:

B4X:
myJob.Download2("http://someaddress with a few spaces.jpg", Array As String(" ", "%20"))

Is the above code correct or am I missing the point :eek:

It works when I pass an address without any spaces but errors out when I do have an address with spaces.

Thanks
 
Last edited:

peacemaker

Expert
Licensed User
Longtime User
How about fixing NulPointerException at
CallSubDelayed2(HttpUtils2Service, "SubmitJob", Me)
?


httpjob_postbytes (B4A line: 30)


End Sub

java.lang.NullPointerException
at peacemaker.playbook.playpadmarket.httpjob._postbytes(httpjob.java:351)
at peacemaker.playbook.playpadmarket.httpjob._poststring(httpjob.java:439)
at peacemaker.playbook.playpadmarket.inet._getconfigver(inet.java:183)
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.keywords.Common$4.run(Common.java:879)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
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: java.lang.RuntimeException: java.lang.NullPointerException
at anywheresoftware.b4a.keywords.Common$4.run(Common.java:882)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
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.keywords.Common$4.run(Common.java:879)
... 9 more
Caused by: java.lang.NullPointerException
at peacemaker.playbook.playpadmarket.httpjob._postbytes(httpjob.java:351)
at peacemaker.playbook.playpadmarket.httpjob._poststring(httpjob.java:439)
at peacemaker.playbook.playpadmarket.inet._getconfigver(inet.java:183)
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)
... 10 more
 

salmander

Active Member
Licensed User
Longtime User
Look few posts back, where Erel has mentioned, it’s a bug in v2.0. He is currently in a process of pushing out an update to B4A. In meantime, he suggested me that download a beta update from the same URL where b4a 2.0 was, instead change the name from b4a_full to beta.exe.

Post back if this helps.
 

peacemaker

Expert
Licensed User
Longtime User
Thanks ! 2.01 indeed works OK with the same source.
 

jaminben

Member
Licensed User
Longtime User

NeoTechni

Well-Known Member
Licensed User
Longtime User
The host section of the URL is not expected to include any illegal characters.
Job.Download2 only takes care of the keys and values parameters: IANA — Example domains.

In your case you will need to use Job.Download:
B4X:
myJob.Download("http://someaddress with a few spaces.jpg".Replace(" ", "+"))

It's %20, not + you need to replace spaces with in most cases
 

Gearcam

Active Member
Licensed User
Longtime User
poststring

Is theire a guide to convert to the new HttpUtils2 post string lines ie.

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


From the old version
HttpUtils.PostString("Job1", ServerUrl, "SELECT MOBusername , MOBpassword FROM MobileUsers where MOBusername ='" & G_Usercode & "'")

It would help me out a lot

Steve
 

CharlesIPTI

Active Member
Licensed User
Longtime User
Still testing FAIL

Erel said:
No, that is not correct.


Error description: An Activity context is required.
This class has a process context.
Adding a global "Activity object" variable will fix this issue.
Occurred on line: 40
HttpUtils.PostString("GetCartState", PostGetCartState,"p_CartNumber=" & 100)
Word: poststring

B4A Version 2.01 HttpUtil2


http Util stuff in class module named sickpuppies
main tries to ...initialize the class then call the web method

as I started moving the magic from the class module to the activity the jobdone in the class now calls this error An Activity context is required.

So the error An Activity context is required. comes up for the HttpUtil sub when its in the class module and for the jobDone sub when its in the class module....
 

Attachments

  • HttpUtil2Test_fromClass.zip
    12.7 KB · Views: 707

Peter Simpson

Expert
Licensed User
Longtime User
This httputils2 is just awesome :)

It too late for me to add it my latest project, too much work involved. I must say that it does make calling urls for xml feeds and retrieving images easier than ever.

Good work Erel :)

Awesome...
 

Gearcam

Active Member
Licensed User
Longtime User
It is almost identical:
B4X:
Dim Job1 As HttpJob
Job1.Initialize("Job1", Me)
Job1.PostString(ServerUrl, "SELECT ...")



Thanks Erel works fine
Any issues with using two or more modules (i will end up with about 10 all with different read writes to different tables in the same database)

Do you use a seperate Sub JobDone (Job As HttpJob) in each module ?

Or just the one in the main module i think for my program it will be easier in each module

Steve
 

Gearcam

Active Member
Licensed User
Longtime User
hi Erel

Now im getting theire

I can get some data like

job1.Initialize("Job1", Me)
job1.PostString(ServerUrl, "SELECT MOBusername , MOBpassword FROM MobileUsers where MOBusername ='" & G_Usercode & "'")

this gives a response like
[{"MOBusername":"123","MOBpassword":"XXXXX"}]

how can i easily either change the request or decode the responce so the two variables are then assined as variables ie MOBusername=123 & MOBpassword=XXXXX

so these can used in further code ?

Steve
 

Gearcam

Active Member
Licensed User
Longtime User
Hi erel
Is their an example of how to do this
Was this how it was done in the original version of httputils as I have tried to use this but get many errors

Steve
 

Gearcam

Active Member
Licensed User
Longtime User
Thanks again Erel
I understand the JSON is not re;ated to the HttpUtils or HttpUtils2
But in the original HttpUtils example you had used the JSON to extract the data which is the part i can not get to run i will retry it all today
Thanks
Steve
 
Top