B4A Library OkHttp - Replaces the Http library

OkHttpUtils2 source code: [B4X] OkHttpUtils2 / iHttpUtils2 / HttpUtils2 source code
It is included as an internal library.
Usage: [B4X] OkHttpUtils2 with Wait For

The current Http library is based on the Android version of Apache HttpClient. Google has stopped updating this SDK a long time ago and they are removing it from Android M. This means that it is a good time now to switch to a different implementation.

Note that if you are using HttpUtils2 (as you should) it is also based on Http library.

The OkHttp library is based on the OkHttp SDK: http://square.github.io/okhttp/
As this is a newer SDK it supports new features such as SSL SNI, SPDY, Patch requests and better performance.

The OkHttp wrapper API is almost identical to Http library API. The main difference is that the object names start with Ok (OkHttpClient, OkHttpResponse and OkHttpRequest).

This library requires Android 2.3+.

Attached is a modified version of HttpUtils2 library (v2.12) that is based on OkHttp instead of Http.

If you want to use the new HttpUtils2 library you need to copy it to the internal libraries folder.

V1.01 - Compatible with B4J.
V1.00 - Adds support for digest authentication.

OkHttpUtils2 v2.20 is attached. It adds support for multipart requests.

Example:
B4X:
Dim j As HttpJob
j.Initialize("j", Me)
Dim fd As MultipartFileData
fd.Initialize
fd.KeyName = "file"
fd.Dir = File.DirAssets
fd.FileName = "image.png"
fd.ContentType = "image/png"
j.PostMultipart("http://...", CreateMap("param1": "value1"), Array(fd))

OkHttp and OkHttpUtils2 libraries are included in the IDE.
 
Last edited:

imgsimonebiliato

Well-Known Member
Licensed User
Longtime User
I use this code, to send notify, but the last 2 rows aren't correct:


B4X:
Dim job As HttpJob

job.Initialize("send message", Me)
job.PostString("https://android.googleapis.com/gcm/send", json.ToString)
job.GetRequest.SetContentType("application/json")
job.GetRequest.SetHeader("Authorization", "key=" & bsUtils.apikey)

The log error say:
B4X:
Error description: Unknown type: anywheresoftware.b4h.okhttp.OkHttpClientWrapper.OkHttpRequest
Are you missing a library reference?
 

StefanoAccorsi

Member
Licensed User
Longtime User
Hi, I need to send a login to a web service through a GET and not a POST. Please don't ask me why: I need to connect to an authentication server that uses this way.

So I tried a simple HttpJob and it is ok:

B4X:
http.Initialize("Login", Me)
http.Download("https://" & RERURL & "/xxx/xx/Login?goto=https%3A%2F%2F" & RERURL & "%2FMapper" & _
    "%2F&IDToken1=" & txtUsername.Text & "&IDToken2=" & txtPassword.Text)

the problem is that the login infos are stored in the header of the html I get as a response and so I can't use the simple Job.GetString: in it I find only the html "body" and not its headers.

So I switched to the more complex OkHttpClient but it doesn't work. I wrote:

B4X:
httpClient.InitializeAcceptAll("Login")
httpReq.InitializeGet("https://" & RERURL & "/xxx/xx/Login?goto=https%3A%2F%2F" & RERURL & "%2FMapper" & _
        "%2F&IDToken1=" & txtUsername.Text & "&IDToken2=" & txtPassword.Text)
httpClient.Execute(httpReq, 1000)

but when executed it never goes to the ResponseSuccess or ResponseError sub:

B4X:
Sub http_ResponseSuccess(Response As OkHttpResponse, TaskId As Int)
    ProgressDialogHide
    Dim listHeaders As List
    listHeaders = Response.GetHeaders.Get("Username")
    Log("Success")
    For i=0 To listHeaders - 1
        Log(listHeaders.Get(i))
    Next
End Sub

Sub http_ResponseError (Response As OkHttpResponse, Reason As String, StatusCode As Int, TaskId As Int)
    ProgressDialogHide
    Log("Error")
End Sub

So here my questions: there's a way to read the headers using the simpler HttpJob?
Otherwise, where's the error in the OkHttpClient implementation?

Thank you.
 

MarcoRome

Expert
Licensed User
Longtime User
Hi, I need to send a login to a web service through a GET and not a POST. Please don't ask me why: I need to connect to an authentication server that uses this way.

So I tried a simple HttpJob and it is ok:

B4X:
http.Initialize("Login", Me)
http.Download("https://" & RERURL & "/xxx/xx/Login?goto=https%3A%2F%2F" & RERURL & "%2FMapper" & _
    "%2F&IDToken1=" & txtUsername.Text & "&IDToken2=" & txtPassword.Text)

the problem is that the login infos are stored in the header of the html I get as a response and so I can't use the simple Job.GetString: in it I find only the html "body" and not its headers.

So I switched to the more complex OkHttpClient but it doesn't work. I wrote:

B4X:
httpClient.InitializeAcceptAll("Login")
httpReq.InitializeGet("https://" & RERURL & "/xxx/xx/Login?goto=https%3A%2F%2F" & RERURL & "%2FMapper" & _
        "%2F&IDToken1=" & txtUsername.Text & "&IDToken2=" & txtPassword.Text)
httpClient.Execute(httpReq, 1000)

but when executed it never goes to the ResponseSuccess or ResponseError sub:

B4X:
Sub http_ResponseSuccess(Response As OkHttpResponse, TaskId As Int)
    ProgressDialogHide
    Dim listHeaders As List
    listHeaders = Response.GetHeaders.Get("Username")
    Log("Success")
    For i=0 To listHeaders - 1
        Log(listHeaders.Get(i))
    Next
End Sub

Sub http_ResponseError (Response As OkHttpResponse, Reason As String, StatusCode As Int, TaskId As Int)
    ProgressDialogHide
    Log("Error")
End Sub

So here my questions: there's a way to read the headers using the simpler HttpJob?
Otherwise, where's the error in the OkHttpClient implementation?

Thank you.

Look THIS
 

StefanoAccorsi

Member
Licensed User
Longtime User

Hi @MarcoRome and thank you! But there's something I still don't understand.

I have to modify the HttpUtils2 (or OkHttpUtils) implementation and create and use this new version? In this case, where could I find the source?

But, since I tried and, after the login call, there was "something" in Job.Tag, I tried to use it as it was the "Headers". But something like:

B4X:
Dim m as Map
m = Job.Tag

led me to a runtime error.
Thank you again.
 

DonManfred

Expert
Licensed User
Longtime User

fbritop

Active Member
Licensed User
Longtime User
When upgrading to OKHttp:

How can we attach the InitializeAcceptAll added to the HttpJob object?. In the old times we did it directly in the httpUtils class but this is not available when using the library. I know that this option is available through the OkHttpClient object, but how do we attach it to the HttpJob?

B4X:
                Dim jobLogin As HttpJob
                jobLogin.Initialize("jobINVITATION", Me)
                Log(url)
                jobLogin.PostString(url,"")
                jobLogin.GetRequest.Timeout=8000   
                startOpen=DateTime.Now
 

Inman

Well-Known Member
Licensed User
Longtime User
Does OkHttp have any issue with saving and restoring cookies automatically? I am facing the following issue:

I have a Reddit client app which was working correctly. I hadn't updated it in over a year but due to some change in Reddit API I am forced to do so now. The app is working fine using HttpUtils and old HttpClient implementation. But when I tried to do it with okHttp (and okHttpUtils2), it does not look like it is saving the user login cookie. For example, after login to Reddit with API (which works and returns the hash and other value correctly), I immediately call the Subscribed API to get a list of subreddits the user is subscribed to. In my old app, it is still returning the correct values in JSON. But in okHttp version it returns an empty {}. I suspect this is because the API cannot detect the logged in user as the Subscribed API relies entirely on cookie to do that.

I saw a post on Stackoverflow which I think is related to this. A solution is also mentioned. Could you please take a look?

http://stackoverflow.com/questions/25461792/persistent-cookie-store-using-okhttp-2-on-android

I am using the following:
  • B4A 6.31
  • okHttp 1.01
  • OkHttpUtils2 2.20
 

ktlua

Member
Licensed User
The current Http library is based on the Android version of Apache HttpClient. Google has stopped updating this SDK a long time ago and they are removing it from Android M. This means that it is a good time now to switch to a different implementation.

Note that if you are using HttpUtils2 (as you should) it is also based on Http library.

The OkHttp library is based on the OkHttp SDK: http://square.github.io/okhttp/
As this is a newer SDK it supports new features such as SSL SNI, SPDY, Patch requests and better performance.

The OkHttp wrapper API is almost identical to Http library API. The main difference is that the object names start with Ok (OkHttpClient, OkHttpResponse and OkHttpRequest).

The following features are currently not available:
- Digest authentication.
- Proxy

This library requires Android 2.3+.

Attached is a modified version of HttpUtils2 library (v2.12) that is based on OkHttp instead of Http.

If you want to use the new HttpUtils2 library you need to copy it to the internal libraries folder.

V1.01 - Compatible with B4J.
V1.00 - Adds support for digest authentication.

OkHttpUtils2 v2.20 is attached. It adds support for multipart requests.

Example:
B4X:
Dim j As HttpJob
j.Initialize("j", Me)
Dim fd As MultipartFileData
fd.Initialize
fd.KeyName = "file"
fd.Dir = File.DirAssets
fd.FileName = "image.png"
fd.ContentType = "image/png"
j.PostMultipart("http://...", CreateMap("param1": "value1"), Array(fd))

I compile and run the program. It gives me error:
(Line:0) null
java.lang.Exception:Sub service_start signature does not matched expected public static anywheresoftware.b4a.pc.RemoveObject anywheresoftware.b4a.samples.httputils.httputilsservice_subs_0.service_start() throws java.lang.Exception
 
Top