OkHttp Android Example Tutorial

Filed Under: Android

OkHttp is a third party library that was introduced by Square in 2013 for sending and receive HTTP-based network requests.

OkHttp Android

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 example tutorial

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.

OkHttp Android Advantages

Some advantages that OkHttp brings to us are:

  1. Connection pooling
  2. Gziping
  3. Caching
  4. Recovering from network problems
  5. Redirects
  6. Retries
  7. Support for synchronous and asynchronous calls

Synchronous vs Asynchronous calls

  • Synchronous calls require an AsyncTask wrapper around it. That means it doesn’t support cancelling a request. Also, AsyncTasks generally leak the Activity’s context, which is not preferred.
  • Asynchronous Calling is the recommneded way since it supports native cancelling, tagging multiple requests and canceling them all with a single method call (by invoking the cancel on the Acitivty instance inside the onPause or onDestroy method).

Before we look into the implementation of OkHttp android, add the following dependency


compile 'com.squareup.okhttp3:okhttp:3.4.1'

Add the permission for internet inside the AndroidManifest.xml file.


<uses-permission android:name="android.permission.INTERNET"/>

OkHttp Android Example Code

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.

OkHttp Query Parameters Example

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/.

OkHttp Android Headers Example

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();

Processing the JSON Response

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();
                        }
                    }
                });

            }
        });

OkHttp Android POST Example

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.

Comments

  1. Zaw Moe Htike says:

    Thank you.

  2. Robin E.W. Creffield says:

    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.

  3. KevinAndro says:

    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?

    1. Zaw Moe Htike says:

      I think response will be always JSON because we are calling Web Service from server.
      If not it, it will occur error

  4. vinoj vedamonickam says:

    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?

  5. Ethan Arnold says:

    In the line HttpUrl.parse(“https://httpbin.org/get).newBuilder(); the closing quote is missing after ‘get’.

  6. pavithra says:

    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

  7. Falguni Patodi says:

    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.

  8. Amir says:

    Hi all ,
    i didn,t understand well that what is OkHttp and its uses …
    plzzz anyone help me to understand and work with it

  9. Tarde says:

    Many thanks. You helped me sort it out.

  10. Anny says:

    Thanks for the post !!

    But, sometimes I receive a error: java.net.ProtocolException: unexpected end of stream. Can you help?

    1. Anupam says:

      Hi Anny,
      Apparently, that’s occurring because of a timeout. You can set custom timeouts. Okhttp supports read, write and connect timeout. Following snippet demonstrates the same.

      OkHttpClient client = new OkHttpClient();
      client.setConnectTimeout(15, TimeUnit.SECONDS); // connect timeout
      client.setReadTimeout(15, TimeUnit.SECONDS); // socket timeout
      client.setWriteTimeout(15, TimeUnit.SECONDS); // write timeout

      Request request = new Request.Builder().url(url).build();
      Response response = client.newCall(request).execute();

  11. Kawarpreet Singh says:

    Best explanation about OkHttp. Thank you so much.

  12. Roberto Corona says:

    Great work, so many thanks!

    1. Anupam says:

      Glad that it was helpful to you Roberto. If you want me to cover any topics feel free to comment below!

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages