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,163
  • HttpUtils2.zip
    8.5 KB · Views: 11,486
Last edited:

socialnetis

Active Member
Licensed User
Longtime User
Erel, one of my apps is having a big explossion on downloads and in the las 2 days I had 7 reports about this error:

B4X:
java.lang.RuntimeException: java.lang.NullPointerException
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:193)
at anywheresoftware.b4a.BA$3.run(BA.java:303)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at socialnetis.funnyapp.httputils2service._vvvvvvvvvvvvvvv4(httputils2service.java:100)
at socialnetis.funnyapp.httputils2service._response_streamfinish(httputils2service.java:153)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
... 10 more

B4X:
java.lang.RuntimeException: java.lang.NullPointerException
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:193)
at anywheresoftware.b4a.BA$3.run(BA.java:303)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3692)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:633)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at socialnetis.funnyapp.httputils2service._vvvvvvvvvvvvvvv4(httputils2service.java:100)
at socialnetis.funnyapp.httputils2service._hc_responseerror(httputils2service.java:124)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
... 10 more

The variable vvvvvvvvvvvvvvv4 is completejob, is seems to be the same error, in response_streamfinish and hc_responseerror.
What could be the problem?
 

jalle007

Active Member
Licensed User
Longtime User
For some some reason JobDone is never fired

B4X:
Sub Process_Globals
   Dim img = "akcija1.jpg"
        Dim  ImageBmp(2) As Bitmap
   Dim x As Int
End Sub

Sub GetImages
Dim i As Int
For i = 0 To 1
    Dim ImageJob As HttpJob
    ImageJob.Initialize("ImageJob", Me)
    ImageJob.Download("http://www.bestbonusmoney.com/android/akcija" & (i+1) & ".jpg")

Next
End Sub

Sub JobDone (Job As HttpJob)

    If Job.Success = True Then
        ImageBmp(x) = Job.GetBitmap
      x=x+1
    End If
Job.Release
End Sub

any idea please?
 

socialnetis

Active Member
Licensed User
Longtime User
This is strange. Did you modify the service code?

Yesterday I had the strange luck that happened to me. It happened while it was downloading something (a page or an image, I don't know for sure which one) and the internet connection goes off, the app finished and I send the report to myself, and was the same problem that was having before.
Is there anyway I can prevent this? Some exception to catch or something, to tell the user to check their internet connection
 

jalle007

Active Member
Licensed User
Longtime User
I noticed that for some reason JobDone is never called in some of my projects. But no matter if I use HTtpUtils 1,2 , HttpClient or DownloadService JobDone is never called. It works in empty projects.

Is there maybe some files that needs to be cleaned when this happen ?
Strange thing here , it works when I compile app at my home pc ....

Edit: this become kind a frustrating for me.
Why don't I get response if job post get or download job is not successfully ?
Still can get "JobDone" fired when it should be
 
Last edited:

jalle007

Active Member
Licensed User
Longtime User
I realize in the end that problem was in Manifest file

There were some leftover of previous HttpUtils settings.

B4X:
<service android:name=".httputilsservice"/>
<receiver android:name=".httputilsservice$httputilsservice_BR"/>

It should say:

B4X:
<service android:name=".httputils2service"/>
<receiver android:name=".httputils2service$httputils2service_BR"/>
took me 2 days to find the problem:sign0161:
 
Last edited:

MaxApps

Active Member
Licensed User
Longtime User
Hi

How do I translate from httputils:
B4X:
HttpUtils.PostString ("test", "http://mysqlplace.com/myscrip.php?tag=tablename&value=data, "http://mysqlplace.com/myscrip.php?tag=tablename&value=data)

to httputils2?

I have tried:
B4X:
Dim job1 As HttpJob
job1.Initialize("job1", Me)
job1.PostString( "http://mysqlplace.com/myscrip.php", "&tag=tabename&value=data")
it show Job as success, but nothing is entered into my mysql database.

Kind regards
Jakob
 

socialnetis

Active Member
Licensed User
Longtime User
Erel, do you know how to handle the problem I mentioned before? I have about 90 error reports, and starting to get 1 star.
Where should I put a try-catch?
 

qsrtech

Active Member
Licensed User
Longtime User
Little addition to the httpjob class

Just thought I post this little idea to help extend the httpjob class. Since the http service is done async, sometimes you might need some extra data to help process the returned data, esp when working with DB's.

A simple idea is to add a "Public Data as Map" (or whatever you want) field to the httpjob class. You can then use this when the job gets "done". Be sure to initialize the "Data" map in the class initialize sub.
 
Last edited:

mattekr

Member
Licensed User
Longtime User
Hi, what is the max number of jobs can run at the same time?
In my code all work fine with 30 request, but with 100 request don't work fine (JobDone wasn't raised).
No error message was raised.

How is possible solve the problem?

Thanks in advice
 

mattekr

Member
Licensed User
Longtime User
Hi, thanks for the reply.
For 4 minutes not happens nothing.
After 4 minutes in the log appears

B4X:
problem reading network stats


java.lang.IllegalStateException: problem parsing idx 1
   at com.android.internal.net.NetworkStatsFactory.readNetworkStatsDetail(NetworkStatsFactory.java:300)
   at com.android.internal.net.NetworkStatsFactory.readNetworkStatsDetail(NetworkStatsFactory.java:250)
   at com.android.internal.os.BatteryStatsImpl.getNetworkStatsDetailGroupedByUid(BatteryStatsImpl.java:5734)
   at com.android.internal.os.BatteryStatsImpl.access$100(BatteryStatsImpl.java:76)
   at com.android.internal.os.BatteryStatsImpl$Uid.computeCurrentTcpBytesReceived(BatteryStatsImpl.java:2457)
   at com.android.internal.os.BatteryStatsImpl$Uid.getTcpBytesReceived(BatteryStatsImpl.java:2446)
   at com.android.internal.os.BatteryStatsImpl.writeSummaryToParcel(BatteryStatsImpl.java:5437)
   at com.android.internal.os.BatteryStatsImpl.writeLocked(BatteryStatsImpl.java:4836)
   at com.android.internal.os.BatteryStatsImpl.writeAsyncLocked(BatteryStatsImpl.java:4818)
   at com.android.server.am.ActivityManagerService.updateCpuStatsNow(ActivityManagerService.java:1652)


   at com.android.server.am.ActivityManagerService$3.run(ActivityManagerService.java:1534)
Caused by: java.io.FileNotFoundException: /proc/net/xt_qtaguid/stats: open failed: ENOENT (No such file or directory)
   at libcore.io.IoBridge.open(IoBridge.java:406)
   at java.io.FileInputStream.<init>(FileInputStream.java:78)
   at com.android.internal.net.NetworkStatsFactory.readNetworkStatsDetail(NetworkStatsFactory.java:269)
   ... 10 more
Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
   at libcore.io.Posix.open(Native Method)
   at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
   at libcore.io.IoBridge.open(IoBridge.java:390)
   ... 12 more

If i do with another page (with different data) was raised same error.
 
Top