Network loading framework OkHttp

Keywords: Android network http

1. What is OkHttp

github address: https://square.github.io/okhttp/

An open source project for processing network requests contributed by Square is the most widely used network framework for Android. Starting with Android 4.4
The underlying implementation of HttpURLConnection adopts OkHttp.

1. Support HTTP/2 and allow all requests to the same host to share a socket;
2. If it is not HTTP/2, the request delay is reduced through the connection pool;
3. Request GZip compressed data by default;
4. Response cache, avoiding the network of repeated requests;

Dependency:
implementation("com.squareup.okhttp3:okhttp:4.9.0")

Test (server used to test http requests):
URL:https://www.httpbin.org/

2. Basic usage of okhttp

OkHttpClient okHttpClient = new OkHttpClient();

Synchronization request:

Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2").build();
                // Prepare the requested Call object
                Call call = okHttpClient.newCall(request);
                try {
                    Response response = call.execute();
                    Log.i(TAG, "getSync: " + response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
FormBody formBody = new FormBody.Builder()
                        .add("a", "1").add("b", "2").build();
Request request = new Request.Builder().url("https://www.httpbin.org/post")
                        .post(formBody).build();
                // Prepare the requested Call object
                Call call = okHttpClient.newCall(request);
                try {
                    Response response = call.execute();
                    Log.i(TAG, "postSync: " + response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }

Asynchronous request:

Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2")
                .build();
        // Prepare the requested Call object
        Call call = okHttpClient.newCall(request);
        //Asynchronous request
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {

            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (response.isSuccessful()) {
                    Log.i(TAG, "getAsync: " + response.body().string());
                }
            }
FormBody formBody = new FormBody.Builder()
                .add("a", "1").add("b", "2").build();
        Request request = new Request.Builder().url("https://www.httpbin.org/post")
                .post(formBody).build();
        // Prepare the requested Call object
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {

            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                Log.i(TAG, "postAsync: " + response.body().string());
            }

3.POST request

The protocol stipulates that the data submitted by POST must be placed in the request body, but the protocol does not specify what encoding method the data must use. The common data coding methods are:
https://www.runoob.com/http/http-content-type.html

1. Content type: application/x-www-form-urlencoded data is encoded as a name / value pair, which is the default type;
2. Content type: multipart / form data data is encoded as a message, which is generally used for file upload;
3. Content type: binary data submitted by application / octet stream. If it is used for file upload, only one file can be uploaded;
4. Content type: submit json data for application/json
...
multipart upload file example (create test code and upload local desktop documents):

 @Test
    public void uploadFileTest() throws IOException {
        OkHttpClient okHttpClient = new OkHttpClient();
        File file1 = new File("C:\\Users\\Administrator\\Desktop\\1.txt");
        File file2 = new File("C:\\Users\\Administrator\\Desktop\\2.txt");
        MultipartBody multipartBody = new MultipartBody.Builder()
                .addFormDataPart("file1", file1.getName(), RequestBody.create(file1, MediaType.parse("text/plain")))
                .addFormDataPart("file2", file2.getName(), RequestBody.create(file2, MediaType.parse("text/plain")))
                .addFormDataPart("a", "1")
                .build();
        Request request = new Request.Builder().url("https://www.httpbin.org/post").post(multipartBody).build();
        Call call = okHttpClient.newCall(request);
        Response response = call.execute();
        System.out.println(response.body().string());
    }

json format upload example:

```java
 @Test
    public void jsonTest() throws IOException {
        OkHttpClient okHttpClient = new OkHttpClient();
        RequestBody requestBody =
                RequestBody.create("{\"a\":1,\"b\":2}", MediaType.parse("application/json"));
        Request request = new Request.Builder().url("https://www.httpbin.org/post").post(requestBody).build();
        Call call = okHttpClient.newCall(request);
        Response response = call.execute();
        System.out.println(response.body().string());

   }

4.Builder builder

OkHttpClient okHttpClient = new OkHttpClient.Builder().build();

5. Interceptor

Concept and detailed use

OkHttpClientokHttpClient=newOkHttpClient.Builder().addInterceptor(newXXX).build();
OkHttpClientokHttpClient=newOkHttpClient.Builder().addNetworkInterceptor(newXXX).build();

6. Caching and cookies

OkHttp implements cache processing according to the Http protocol rules. For example, after we initiate the first request, if we need to enter it later
Line the same request. At this time, if the caching rules are met, the network communication with the server can be reduced and the response can be read directly from the local file cache
Return to requester. However, by default, OkHttp's cache is off and needs to be turned on.


Interceptor and cache code example:

 @Test
    public void interceptorTest() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .cache(new Cache(new File("C:\\Users\\Administrator\\Desktop"),
                        1024 * 1024)).addNetworkInterceptor(new Interceptor() {
                    @NotNull
                    @Override
                    public Response intercept(@NotNull Chain chain) throws IOException {
                        System.out.println("version:" + chain.request().header("version"));
                        return chain.proceed(chain.request());
                    }
                }).addInterceptor(new Interceptor() {
                    @NotNull
                    @Override
                    public Response intercept(@NotNull Chain chain) throws IOException {
                        //Preprocessing
                        Request request = chain.request().newBuilder().addHeader("os", "android")
                                .addHeader("version", "1.0").build();
                        Response response = chain.proceed(request);
                        //Post processing
                        return response;
                    }
                }).build();

        Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2").build();
        // Prepare the requested Call object
        Call call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            System.out.println(response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Cookie is the data (usually encrypted) stored on the user's local terminal by some websites in order to identify the user's identity and track the session (such as determining the login status), which is temporarily or permanently saved by the user's client computer

About the use of cookie s:

public class CookieUnitTest {
    Map<String, List<Cookie>> cookies = new HashMap<>();

    @Test
    public void cookieTest() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .cookieJar(new CookieJar() {
                    @Override
                    public void saveFromResponse(@NotNull HttpUrl httpUrl, @NotNull List<Cookie> list) {
                        cookies.put(httpUrl.host(), list);
                    }

                    @NotNull
                    @Override
                    public List<Cookie> loadForRequest(@NotNull HttpUrl httpUrl) {
                        List<Cookie> cookies = CookieUnitTest.this.cookies.get(httpUrl.host());
                        return cookies == null ? new ArrayList<>() : cookies;
                    }
                })
                .build();
        FormBody formBody = new FormBody.Builder().add("username", "lanceedu")
                .add("password", "123123").build();
        Request request = new Request.Builder().url("https://www.wanandroid.com/user/login")
                .post(formBody).build();
        // Prepare the requested Call object
        Call call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            System.out.println(response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }


        request = new Request.Builder().url("https://www.wanandroid.com/lg/collect/list/0/json")
                .build();
        // Prepare the requested Call object
        call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            System.out.println(response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

Returned data:

{"data":{"admin":false,"chapterTops":[],"coinCount":2542,"collectIds":[17188,18965,20087,19623],"email":"","icon":"","id":86459,"nickname":"lanceedu","password":"","publicName":"lanceedu","token":"","type":0,"username":"lanceedu"},"errorCode":0,"errorMsg":""}
{"data":{"curPage":1,"datas":[{"author":"xiaoyang","chapterId":440,"chapterName":"official","courseId":13,"desc":"<p>Gson You must be familiar with it. It is used on a large scale in many projects.</p>\r\n<p>For example, common:</p>\r\n<pre><code>Network request\r\n    -&gt;return Json data\r\n    -&gt;Gson Resolve to object\r\n    -&gt;Render Page \r\n</code></pre><p>Many times, historical projects contain many Gson Resolve object in UI The operation of threads, or even in sub threads, will actually affect the page rendering speed.</p>\r\n<p>Everyone knows Gson For object resolution, if there is no separate configuration TypeAdapter,In fact, the interior is full of reflection.</p>\r\n<p>Here comes the question:</p>\r\n<p><strong>Is there any low intrusion scheme that can remove reflection operations as much as possible to improve operation efficiency? Just describe the idea.</strong></p>","envelopePic":"","id":223224,"link":"https://Wanandroid. COM / Wenda / show / 19623 "," nicedate ":" 2021-10-15 16:52 "," origin ":", "originid": 19623, "publishtime": 1634287963000, "title": "is there a low intrusion optimization scheme for serializing objects in Gson? "," userId":86459,"visible":0,"zan":0},{"author":"xiaoyang","chapterId":360,"chapterName ":" Xiaobian publishing "," courseid ": 13," desc ":" <p>This is a post to collect suggestions and functions. < / P > \ R \ n < p > if you have: < / P > \ R \ n < ol > \ R \ n < li > functions you want to add; < / Li > \ R \ n < li > what you think needs to be improved at present; < / Li > \ R \ n < / OL > \ R \ n < p > welcome to put forward. You will arrange to update ~ < / P > "," envelope pic ":" "," Id ": 223223223," link ":" https://www.wanandroid.com/wenda/show/20087 ","niceDate":"2021-10-15 16:51"," Origin ":" "," originid ": 20087," publishtime ": 1634287899000," title ":" give wanandroid a comment! "," userId":86459,"visible":0,"zan":0},{"author":"xiaoyang","chapterId":440,"chapterName ":" official "," courseid ": 13," desc ":" <p>For Activity reconstruction, let's explore several questions: < / P > \ R \ n < ol > \ R \ n < li > currently, the app is running in the foreground. Is it possible that the Activity not at the top of the stack will be recycled because of insufficient system resources, such as memory? < / Li > \ R \ n < li > when the app is running in the background, the app process is not killed, and its internal Activity will be recycled? < / Li > \ R \ n < li > when the app is running in the background, AP Will the process of p be killed? < / Li > \ R \ n < / OL > \ R \ n < p > if you have the ability, it is recommended to cooperate with the source code in the interpretation process, and you do not have to answer all ~ < / P > "," envelope pic ":" "," Id ": 210658," link ":" https://www.wanandroid.com/wenda/show/18965 ","niceDate":"2021-08-03 10:43","origin":"","originId":18965,"publishTime":1627958636000,"title":" Daily question | some questions worth exploring about Activity reconstruction "," userId":86459,"visible":0,"zan":0},{"author":"","chapterId":502,"chapterName ":" self service "," courseid ": 13," desc ":" "," envelope pic ":" "," Id ": 173169," link ":" https://mp.weixin.qq.com/s/N4e6AkhNgI3mcbWFlqhYPQ ","niceDate":"2021-02-05 17:22","origin":"","originId":17188,"publishTime ": 1612516968000," title ":" the first introduction to Gradle series "," userId":86459,"visible":0,"zan":0}],"offset":0,"over":true,"pageCount":1,"size":20,"total":4},"errorCode":0,"errorMsg ":"}

PS: the API for playing Android is used here (you can access the favorite articles only after you stay logged in): https://www.wanandroid.com/blog/show/2



Status of cookie s: link

This article demo: https://github.com/gujunhe/NetworkDemo.git

Posted by dprichard on Sat, 30 Oct 2021 12:08:34 -0700