OkHttp is a third party library that was introduced by Square in 2013 for sending and receive HTTP-based network requests.
Initially Android had only two HTTP clients: HttpURLConnection and Apache HTTP Client; for sending and receiving data from the web. Each of these clients required a lot of boilerplate code to be written inside the AsyncTask or the background thread methods. Moreover, these clients have their own sets of limitations when it came to cancelling an HTTP request or connection-pooling. OkHttp android provides an implementation of HttpURLConnection and Apache Client interfaces by working directly on a top of java Socket without using any extra dependencies.
Some advantages that OkHttp brings to us are:
Before we look into the implementation of OkHttp android, add the following dependency
compile 'com.squareup.okhttp3:okhttps:3.4.1'
Add the permission for internet inside the AndroidManifest.xml
file.
<uses-permission android:name="android.permission.INTERNET"/>
The MainActivity.java for Synchronous Calls is given below.
package com.journaldev.okhttp;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
OkHttpClient client = new OkHttpClient();
TextView txtString;
public String url= "https://reqres.in/api/users/2";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtString= (TextView)findViewById(R.id.txtString);
OkHttpHandler okHttpHandler= new OkHttpHandler();
okHttpHandler.execute(url);
}
public class OkHttpHandler extends AsyncTask {
OkHttpClient client = new OkHttpClient();
@Override
protected String doInBackground(String...params) {
Request.Builder builder = new Request.Builder();
builder.url(params[0]);
Request request = builder.build();
try {
Response response = client.newCall(request).execute();
return response.body().string();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
txtString.setText(s);
}
}
}
For Asynchronous Calls the MainActivity.java should be defined as:
package com.journaldev.okhttp;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
TextView txtString;
public String url= "https://reqres.in/api/users/2";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtString= (TextView)findViewById(R.id.txtString);
try {
run();
} catch (IOException e) {
e.printStackTrace();
}
}
void run() throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
call.cancel();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String myResponse = response.body().string();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
txtString.setText(myResponse);
}
});
}
});
}
}
We’ve used a test API from here. The response string returned is of the JSON format that gets printed on the screen. You can try out other open source API’s like Github API, Stackoverflow etc.
If there are any query parameters we can easily pass them using an HttpUrl.Builder
class.
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://httpbin.org/get).newBuilder();
urlBuilder.addQueryParameter("website", "www.journaldev.com");
urlBuilder.addQueryParameter("tutorials", "android");
String url = urlBuilder.build().toString();
Request request = new Request.Builder()
.url(url)
.build();
The above url was obtained from https://resttesttest.com/.
If there are any authenticated query parameters, they can be added in the form of headers as shown below:
Request request = new Request.Builder()
.header("Authorization", "replace this text with your token")
.url("your api url")
.build();
We can parse the JSON data to get the relevant params and display them in a TextView as below code.
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
call.cancel();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String myResponse = response.body().string();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONObject json = new JSONObject(myResponse);
txtString.setText(json.getJSONObject("data").getString("first_name")+ " "+json.getJSONObject("data").getString("last_name"));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
});
Up until now, we’ve looked at getting a response by calling a few API’s. To post a data to the server we need to build our request in the following way.
public class MainActivity extends AppCompatActivity {
public String postUrl= "https://reqres.in/api/users/";
public String postBody="{\n" +
" \"name\": \"morpheus\",\n" +
" \"job\": \"leader\"\n" +
"}";
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
postRequest(postUrl,postBody);
} catch (IOException e) {
e.printStackTrace();
}
}
void postRequest(String postUrl,String postBody) throws IOException {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, postBody);
Request request = new Request.Builder()
.url(postUrl)
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
call.cancel();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("TAG",response.body().string());
}
});
}
}
In the above code, we’ve used the MediaType class that’s a part of OkHttp to define the type of data being passed. We’ve used the test API URL from https://reqres.in/. The post(RequestBody body)
method is called on the RequestBuilder with the relevant value. The Log displays the following response. {"name":"morpheus","job":"leader","id":"731","createdAt":"2017-01-03T17:26:05.158Z"}
. OkHttp is the recommend HttpClient that’s used inside the Retrofit Networking Library. We’ll look into this in the next tutorial. We’ve added three buttons in the layout to invoke each of the methods, postRequest(), run() and the AsyncTask wrapper class. You can download the final Android OkHttp Project from the link below.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Great work, so many thanks! i get excption when i get data from api by using JSONOBJECT say: i can’t convert JsonObject to JsonArray
- sam
Thanks How to handle message mapping ? I mean how to specify the controller that will handle the message on server side ?
- arnaud
How to call Api in login and register form using okhttp request
- sri
Thank you.
- Zaw Moe Htike
This is the only method that I’ve got to work so far and been battling with it all day (complete novice). Confused as to the “final String myResponse = response.body().string();” in the GET example - means the response string can never be changed even if the server goes down.
- Robin E.W. Creffield
How to check the response is in JSon format or something else?how to set setlenient(true)? i need to check whether the response is json or not?
- KevinAndro
How to call the api and return the response without using asynctask.Just i call the method it should return the response.how to do this?
- vinoj vedamonickam
In the line HttpUrl.parse("https://httpbin.org/get).newBuilder(); the closing quote is missing after ‘get’.
- Ethan Arnold
08-02 18:31:09.003 2195-6340/com.google.android.gms.persistent E/WakeLock: release without a matched acquire! 08-02 18:31:10.041 6718-6718/? E/memtrack: Couldn’t load memtrack module (No such file or directory) 08-02 18:31:10.041 6718-6718/? E/android.os.Debug: failed to load memtrack module: -2 08-02 18:32:59.076 2195-6340/com.google.android.gms.persistent E/WakeLock: release without a matched acquire! 08-02 18:33:00.019 6755-6762/? E/art: Failed writing handshake bytes (-1 of 14): Broken pipe 08-02 18:34:49.151 2195-6340/com.google.android.gms.persistent E/WakeLock: release without a matched acquire! 08-02 18:36:39.225 2195-6340/com.google.android.gms.persistent E/WakeLock: release without a matched acquire! 08-02 18:38:29.300 2195-6340/com.google.android.gms.persistent E/WakeLock: release without a matched acquire! 08-02 18:38:48.473 2195-6346/com.google.android.gms.persistent E/WakeLock: release without a matched acquire! 08-02 18:39:28.562 2195-6842/com.google.android.gms.persistent E/WakeLock: release without a matched acquire! Help me for this error
- pavithra
I made a library using okhttp synchronous call and the test cases work fine but when i import the library in my app and access the functions i have to make call asynchronous as synchronous call stops the app, but by using asynchronous, i have to click twice on the buttons to get the response. I would really some help. Thankyou.
- Falguni Patodi