Almost all web frameworks today are written in Okhttp, RXJava, and RetroFIT. Because there is nothing recently, I take the time to summarize this knowledge: because these things even in a phase of speaking, many students will feel meng, so here I am ready to talk about the use of each thing first, and then explain how to use.

I recently watched TASK Force X/Suicide Squad and thought it was good. With a mixed child mentality of life, in fact, quite easy! So a picture town building! I can send you the habit!

Knowledge of this article

  • The use of OkHttp
  • OkHttp uploads files
  • Some advanced uses of OkHttp

1. Simple use of OkHttp

Here comes an important note first: network authority must be added, must be added!!

There’s only one order to remember to use OkHttp

  • Create the OkHttpClient object
  • Create Request Request content
  • Send the request
  • Create a callback for the request

Basically remember the above steps to implement a simple request!

1.1 Simple GET Request

Since the above mentioned corresponding steps, we will follow the above steps to write it!!

1.1.1 Creating the OkHttpClient object

OkHttpClient httpClient = new OkHttpClient();
Copy the code

Create an object, nothing to say!!

1.1.2 Creating Request Contents

 Request request = new Request.Builder()
                .method("GET", null)
                .url("https://www.baidu.com/")
                .build();
Copy the code

Method sets the request type; The URL is set to the corresponding request address! Second, Request is a builder’s build pattern. The rest is not much to tell. , if the novice, do not care so much why, the effect is important!!

1.1.3 Sending a Request

Call call = httpClient.newCall(request);
Copy the code

You’re just letting httpClient know what it’s asking for, right

1.1.4 Creating the content returned by the request

    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.e(TAG, "Request failed because:" + e);
        }

        @Override
        public void onResponse(Call call, final Response response) throws IOException {
            Headers headers = response.headers();
            Set<String> names = headers.names();
            for (String name : names) {
                Log.e(TAG, "Requested header" + name);
                String value = headers.get(name);
                Log.e(TAG, "Value:" + value + "\n----------------------------------");
            }

            final String date = response.body().string();
            mHandler.post(new Runnable() {
                @Override
                public void run() { mTvShow.setText(date); }}); }});Copy the code

There is much to be said here:

  1. When you see FATAL EXCEPTION: OkHttp Dispatcher, congratulations, you hit the first trap! This is mainly because response.body().string() can only be called once. If you call it twice in your code, the above exception will occur;

  2. When you make an asynchronous request, you can’t modify the UI in the child thread, so HERE I use a Handler to handle the corresponding content

  3. If you want to see the corresponding content, then look at the for loop, you can print it, you can see the following content, if you don’t understand, ask your background staff! Be open-minded.

    Accept-ranges →bytes cache-control →no-cache Connection → keep-alive content-Length →227 content-type →text/ HTML Date →Wed, 05 Sep 2018 03:41:58 GMT Etag →"5b7b7f40-e3"Last-modified →Tue, 21 Aug 2018 02:56:00 GMT Pragma →no-cache Server →BWS/1.1 set-cookie →BD_NOT_HTTPS=1; path=/; Max-age =300 strict-transport-Security →max-age=0 X-UA-Compatible →IE=Edge, Chrome =1Copy the code
  4. If it fails, an exception will be sent back to you in onFailure!!

Post the whole code for you!

/*1. Create the OkHttpClient object */ OkHttpClient httpClient = new OkHttpClient(); Request = new request.builder ().method()"GET", null)
                .url("https://www.baidu.com/") .build(); */ Call Call = httpClient.newCall(request); /*4. Create the requested callback */ call.enqueue(newCallback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "Request failed because:" + e);
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                Headers headers = response.headers();
                Set<String> names = headers.names();
                for (String name : names) {
                    Log.e(TAG, "Requested header" + name);
                    String value = headers.get(name);
                    Log.e(TAG, "Value:" + value + "\n----------------------------------");
                }


                final String date = response.body().string();
                mHandler.post(new Runnable() {
                    @Override
                    public void run() { mTvShow.setText(date); }}); }});Copy the code

The above steps can normally request the corresponding data, if there is no data, take a good look at the code!

1.2 Simple POST Request

A POST request is basically a form that is one step further than a GET request. This is a FormBody object that sets the form as a key and value, so here’s how to do it, and then I’ll POST the code.

The form is written like this:

FormBody formBody = new FormBody.Builder()
                .add("key"."value")
                .build();
Copy the code

The add method can be called multiple times, adding the corresponding key and value;

The overall code is like this!!

/*1. Create the OkHttpClient object */ OkHttpClient httpClient = new OkHttpClient(); FormBody FormBody = new formBody.builder ().add()"key"."value") .build(); Request = new request.builder ().url()"https://www.baidu.com/") .post(formBody) .build(); */ Call Call = httpClient.newCall(request); /* create the requested callback */ call.enqueue(new)Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "Request failed because:" + e);
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                Headers headers = response.headers();
                Set<String> names = headers.names();
                for (String name : names) {
                    Log.e(TAG, "Requested header" + name);
                    String value = headers.get(name);
                    Log.e(TAG, "Value:" + value + "\n----------------------------------");
                }


                final String date = response.body().string();
                mHandler.post(new Runnable() {
                    @Override
                    public void run() { mTvShow.setText(date); }}); }}); }Copy the code

POST and GET requests are just different in the way they are requested. POST is more secure and everything is delivered by the form!

2. Upload files using OkHttp3

Here to an important note: to write SD card permission must be added, must be added!!

OkHttp3 also allows you to upload a file.

  • Create the OkHttpClient object
  • Create the Request Request content and all required parameters (this differs from other requests)
    • Access to the file
    • Set the type of the file to be uploaded
    • Get request body
  • Create a request
  • Create a callback for the request

Because the other content is similar, except the content about the form, I will focus on this form.

 RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("title"."Zhang")
                .addFormDataPart("image"."zhangsan.jpg", RequestBody.create(MediaType.parse("application/octet-stream"), new File(Environment.getExternalStorageDirectory().getParent() + "/0/123.png")))
                .build();
Copy the code

General this kind of upload file, basically is to transfer the corresponding user picture, modify the picture of what! Because the server needs to replace the corresponding picture according to the picture you upload. Back to the configuration above:

  1. Above the first “title” that parameter, should be a group of key, value form, basically according to the server set parameters prevail, can have more groups!
  2. The second “image” parameter is basically the key of this form, the name of the image, the location of the image. This locks an image, and a corresponding RequestBody object is built.

The overall code looks like this:

/*1. Create the OkHttpClient object */ OkHttpClient httpClient = new OkHttpClient(); */ RequestBody RequestBody = new MultipartBody.builder ().setType(multipartbody.form).addFormDatApart ("title"."Zhang")
                .addFormDataPart("image"."zhangsan.jpg", RequestBody.create(MediaType.parse("application/octet-stream"), new File(Environment.getExternalStorageDirectory().getParent() + "/0/123.png"))) .build(); Request = new request.builder ().header()"key"."value")
                .url("https://www.baidu.com/") .post(requestBody) .build(); */ Call Call = httpClient.newCall(request); /* create the requested callback */ call.enqueue(new)Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "onFailure: " + e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e(TAG, "onResponse: "+ response.body().string()); }});Copy the code

Oh, I forgot to mention that images are transferred as streams. So “application/ OCtet-stream “is configured in this format. What about other formats? Give everybody a comparison table: consult OK.

parameter instructions
text/html HTML format
text/plain Plain text format
text/xml XML format
image/gif GIF image format
image/jpeg JPG image format
image/png PNG image format
application/xhtml+xml XHTML
application/xml XML data format
application/atom+xml Atom XML aggregation format
application/json JSON data format
application/pdf PDF format
application/msword Word Document Format
application/octet-stream Binary stream data

Basically you change the above code to change it can upload files!! Simple as that…

3. High-end configuration of OkHttp

3.1 Configuration of some basic parameters of OkHttp

Configure request times, connection timeouts, and so on

OkHttpClient httpClient = new okhttpclient.builder () // set the appropriate connectionPool. ConnectionPool(new connectionPool() .connecttimeout (15, timeunit.seconds) // writeTimeout. WriteTimeout (15, timeunit.seconds) // readTimeout. ReadTimeout (20, TimeUnit.SECONDS) .build();Copy the code

3.2 A brief understanding of the OkHttp interceptor

Often in a project, there are questions about common request parameters, and that’s where the OkHttp interceptor comes in! What is an interceptor? Simply put, it’s like burying a point. Will walk every interceptor when requested! Add what you want to add what you want to add, here we explain through a few examples you can roughly understand!

3.2.1 Log Interceptor

Take a look at the code first, and then I’ll explain it accordingly:

public class LogInterceptor implements Interceptor { private static final String TAG = LogInterceptor.class.getSimpleName(); @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); /* Print the corresponding content before the request */ log.e ("url", String.format("Sending request %s on %s %n %s", request.url(), chain.connection(), request.headers())); Proceed (request) */returnchain.proceed(request); }}Copy the code

Here is a direct print of a corresponding LOG, can obtain some request parameters, here is explained:

  1. Only one Url can be printed when your request is a GET request, i.erequest.url()The headers obtained by the GET request is empty because the request has no form information.
  2. chain.connection()When you use the exception log interceptor, it returns null
  3. chain.proceed(request)Represents the result of the request response, so you can also modify the return result!!

3.2.2 Redirect an interceptor to a URL link

This is interesting. When you request an interceptor, it normally returns the content baidu returns, but what happens if you change the url? Of course, it will return your modified return address… So let’s see how we do that

public class ResetInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {

        Request newRequest = new Request.Builder()
                .method("GET", null)
                .url("https://fanyi.baidu.com/translate?aldtype=16047&query=%E8%BF%9B%E5%BA%A6%0D%0A&keyfrom=baidu&smartresult=dict&lang=auto 2zh#zh/en/%E9%87%8D%E7%BD%AE")
                .build();

        returnchain.proceed(newRequest); }}Copy the code

Request Request = chain.request(); This method returns a Request that was created at the time it was created, so you can create a new Request directly by using the interceptor. In fact, you are writing the content of the previous all over again! That’s it…

3.2.3 Adding corresponding public request parameters

In fact, this implementation is similar to the above, that is, replace the corresponding content of the Request! However, you should consider that GET requests and POST requests should be handled differently, depending on the situation. Otherwise you can’t achieve the effect you want! So let’s say it separately here. A GET request concatenates parameters to the Url, while a POST request concatenates parameters to the form, so it must be different!!

1. Add public request parameters to the GET request

Here’s a bit of code to try it out:

    HttpUrl build = originalRequest.url().newBuilder()
            .addQueryParameter("key1"."value1")
            .addQueryParameter("key2"."value2")
            .addQueryParameter("key3"."value3")
            .addQueryParameter("key4"."value4")
            .addQueryParameter("key5"."value5")
            .build();

    Request request = originalRequest.newBuilder().url(build).build();
Copy the code

This allows you to add the appropriate public request parameters. Originally, I thought newBuilder() was creating a new content. It actually takes the previous content and adds the following content to it. So the rest of this content will not be affected!!

GET requests append parameters to the URL.

2. Add public request parameters to the POST request

Let’s start with a bit of code:

Request requestBuilder = originalRequest.newBuilder()
        .addHeader("key1"."value1")
        .addHeader("key2"."value2")
        .addHeader("key3"."value3")
        .addHeader("key4"."value4")
        .addHeader("key5"."value5")
        .build();
Copy the code

Similar to the above, but written differently! Because the POST request adds the corresponding header.

The overall code is as follows:

public class PublicInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();

        if ("GET".equals(request.method())) {HttpUrl build = request.url().newBuilder().addQueryParameter()"key1"."value1")
                    .addQueryParameter("key2"."value2")
                    .addQueryParameter("key3"."value3")
                    .addQueryParameter("key4"."value4")
                    .addQueryParameter("key5"."value5")
                    .build();

            request = request.newBuilder().url(build).build();
        } else if ("POST".equals(request.method())) {
            request = request.newBuilder()
                    .addHeader("key1"."value1")
                    .addHeader("key2"."value2")
                    .addHeader("key3"."value3")
                    .addHeader("key4"."value4")
                    .addHeader("key5"."value5")
                    .build();
        }

        returnchain.proceed(request); }}Copy the code

Finally, add the corresponding Interceptor to OkHttp.


Added on 15 October 2018:

In a POST request, the request parameters should be added to the body, so the above code is broken!

Replace it with the following:

        if(originalRequest.body() instanceof FormBody) {// Create a new request formBody.builder Builder = new FormBody.builder (); FormBody body = (FormBody) originalRequest.body(); // Add the previous parametersfor(int i = 0; i < body.size(); i++) { builder.add(body.encodedName(i), body.encodedValue(i)); } // Add a new parameter builder.add("key1"."value1");
            builder.add("key2"."value2");
            builder.add("key3"."value3");
            builder.add("key4"."value4");
            builder.add("key5"."value5"); . / / construct new request body originalRequest = originalRequest newBuilder (), post (builder. The build ()). The build (); }Copy the code

Sorry for the above error, because I did not understand the HTTP content, please forgive me!!


Basically when using so many problems, some may not explain, if there is anything not in place, timely supplement!! Have question message, I saw certainly can reply you!!

Github address is available