Android: OkHttp synchronous request and asynchronous request

1. Foreword

In my previous work on network requests, I used post requests. After learning about them, I found that there are many types of requests. The following focuses on the synchronous requests and asynchronous requests of get and post.

2. Specific content

1. Characteristics of Okhttp:

  • Supports HTTP/2 and allows all requests to the same host to share the socket;
  • If it is not HTTP/2, the request delay is reduced through the connection pool;
  • GZip compressed data is requested by default;
  • Response caching avoids repeated network requests;

Synchronization request of 2.get

Test URL needed:

https://httpbin.org

The test code is as follows:

public class OkhttpTestActivity extends AppCompatActivity {

    private OkHttpClient okHttpClient;//New okHttp requester

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_okhttp_test);
        okHttpClient = new OkHttpClient();
    }
    public void getSync(View view){//get synchronization request
        /**
         * In brackets are the requested domain name and parameters that need to be uploaded
         * If you need to upload parameters, just add one after the request domain name? a=1&b=2
         */

        new Thread(){
            @Override
            public void run() {
                Request request = new Request.Builder().url("https://httpbin.org/get?a=1 & amp;b=2").build();
                //A call object ready for request
                Call call = okHttpClient.newCall(request);
                try {
                    Response response = call.execute();
                    System.out.println(response.body().string());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                super.run();
            }

        }.start();


    }
}

Screenshot of running results

The problems encountered when using get synchronous requests are as follows

This is how I wrote code before

 public void getSync(View view){//get synchronization request
        /**
         * In brackets are the requested domain name and parameters that need to be uploaded
         * If you need to upload parameters, just add one after the request domain name? a=1&b=2
         */

        new Thread(){
            @Override
            public void run() {
                Request request = new Request.Builder().url("https://httpbin.org/get?a=1 & amp;b=2").build();
                //A call object ready for request
                Call call = okHttpClient.newCall(request);
                try {
                    Response response = call.execute();
                    System.out.println(response.body().toString());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                super.run();
            }

        }.start();

Use response.body().toString() when getting the request body; the error is reported as follows

Modify plan:

 public void getSync(View view){//get synchronization request
        /**
         * In brackets are the requested domain name and parameters that need to be uploaded
         * If you need to upload parameters, just add one after the request domain name? a=1&b=2
         */

        new Thread(){
            @Override
            public void run() {
                Request request = new Request.Builder().url("https://httpbin.org/get?a=1 & amp;b=2").build();
                //A call object ready for request
                Call call = okHttpClient.newCall(request);
                try {
                    Response response = call.execute();
                    System.out.println(response.body().string());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                super.run();
            }

        }.start();


    }

Just change the request body to response.body().string()

Summary: Synchronous requests must wait for call.execute to complete before executing the next code.

Asynchronous request of 3.get

Supplementary knowledge points:

1. The difference between asynchronous requests and synchronous requests: Asynchronous requests call the enqueue method. Then pass a callback object to the enqueue method, and you need to use the two interface callbacks in the callback method. There are two interfaces in callback that need to be implemented, one is the callback interface for request failure and the other is the callback interface for end of request.
2. It should be noted that the request code is 200 success and 404 failure. Whether it is 200~299 or 404, the end interface will be called, so when the onResponse interface is called, it does not mean that the interface call is successful.
3. When response is called, it only means that the communication between us and the server is successful, and the data processing may not be successful.
4. Between 200~300 means success, 300~400 means redirection, 400~~500 means server error.

public class OkhttpTestActivity extends AppCompatActivity {

    private OkHttpClient okHttpClient;//New okHttp requester

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_okhttp_test);
        okHttpClient = new OkHttpClient();
    }


    public void getAync(View view) {//get asynchronous request
        Request request = new Request.Builder().url("https://httpbin.org/get?a=1 & amp;b=2").build();
        //A call object ready for request
        Call call = okHttpClient.newCall(request);
        //The difference between asynchronous requests and synchronous requests: Asynchronous requests call the enqueue method and then pass a callback object to the enqueue method. There are two interfaces in the callback that need to be implemented. One is the callback interface for request failure and the other is the callback interface for the end of the request.
        //It should be noted that the request code is 200 success and 404 failure. Whether it is 200~299 or 404, the end interface will be called, so when the onResponse interface is called, it does not mean that the interface call is successful.
        //When the response appears 200, it only means that the communication between us and the server is successful, and the data processing may not be successful.
        //200~300 represents success, 300~400 represents redirection, 400~~500 represents server error.
        call.enqueue(new Callback() {
            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful()) {
                    System.out.println(response.body().string());
                }
            }

            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {

            }

        });

    }
}

Run results

Summary: Asynchronous requests will not wait for the server request to be completed before executing the subsequent code. Enqueue will create child threads for us internally. We do not need to create child threads ourselves.

4.post synchronous request

Note:The request created by OkHttp by default is a get request

The difference between get request and post request: get request needs to be added after the url, but post request needs to put the request parameters in the request body.

Test code:

public class OkhttpTestActivity extends AppCompatActivity {

    private OkHttpClient okHttpClient;//New okHttp requester

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_okhttp_test);
        okHttpClient = new OkHttpClient();
    }

    public void postSync(View view) {//post synchronization request
        FormBody formBody = new FormBody.Builder().add("a", "1").add("b", "2").build();
        Request request = new Request.Builder().url("https://httpbin.org/post").post(formBody).build();
        new Thread(){
            @Override
            public void run() {
                //A call object ready for request
                Call call = okHttpClient.newCall(request);
                try {
                    Response response = call.execute();
                    System.out.println(response.body().string());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                super.run();
            }
        }.start();
    }
}

Test results:

5.post asynchronous request

Test code

public class OkhttpTestActivity extends AppCompatActivity {

    private OkHttpClient okHttpClient;//New okHttp requester

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_okhttp_test);
        okHttpClient = new OkHttpClient();
    }

    public void postAync(View view) {//post asynchronous request
        FormBody formBody = new FormBody.Builder().add("a", "1").add("b", "2").build();
        Request request = new Request.Builder().url("https://httpbin.org/post").post(formBody).build();
        //A call object ready for request
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {

            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                System.out.println(response.body().string());

            }
        });
    }

}

Test results

6. Test the requested page layout

I have placed four buttons on a page with the following code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ui.study.OkhttpTestActivity">
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getSync"
        android:text="GET synchronization request"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getAync"
        android:text="GET asynchronous request"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="postSync"
        android:text="POST synchronization request"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="postAync"
        android:text="POST asynchronous request"/>

</LinearLayout>

Summary: The parameter positions of post request and get request are different. Post should be placed in FormBody. Others are not much different. I hope it can help you in the end.