美文网首页
OkHttp的使用

OkHttp的使用

作者: 禄眠 | 来源:发表于2019-12-06 16:10 被阅读0次

介绍

OkHttp是一个网络框架库,在之前已经介绍过另一个网络框架库Volley,这次我们再了解一下OkHttp

本文只是介绍基本的使用,如果需要更加详细的介绍,可以参考了以下这篇文章:

Android OkHttp常用详解

使用

按照惯例,先添加依赖:

implementation 'com.squareup.okhttp3:okhttp:4.2.2'

网络请求主要为Get请求和Post请求,其中Get请求又可分为同步和异步

先介绍一下`Get·请求的同步方式

new Thread(new Runnable() {
    @Override
    public void run() {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
            .url("https://www.baidu.com")
            .get() // 默认为get方式,可不写
            .build();
        Call call = client.newCall(request);
        try {
            Response response = call.execute();
            if (response.isSuccessful()) {
                String string = response.body().string();
                // 可进行相关UI更新操作,但必须是在主线程中
                Log.d(TAG, String.format("response:%s", string));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

再来看一下Get请求的异步方式:

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
    .url("https://www.baidu.com")
    .build();
Call call = client.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 {
        if (response.isSuccessful()) {
            String string = response.body().string();
            // 可进行相关UI更新操作,但必须是在主线程中
            Log.d(TAG, String.format("response:%s", string));
        }
    }
});

可以看到两种方式基本相同,

同步方式需要手动创建子线程,使用call.execute()来获得Response对象;

异步方式不需要手动创建子线程,使用call.enqueue(callback),在回调中返回Response对象

这里贴出之前的Volly的Get请求代码:

RequestQueue requestQueue = Volley.newRequestQueue(this);
String url = "https://www.baidu.com";
StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, url,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                // 请求成功
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // 请求失败
            }
        });
requestQueue.add(stringRequest);

接下来看一下Post请求的实现方式:

OkHttpClient client = new OkHttpClient();
FormBody formBody = new FormBody.Builder()
    .add("name", "Tom")
    .build();
Request request = new Request.Builder()
    .url("https://www.baidu.com/")
    .post(formBody)
    .build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(@NotNull Call call, @NotNull IOException e) {
        Log.d(TAG, String.format("error:%s", e.getMessage()));
    }

    @Override
    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
        if (response.isSuccessful()) {
            String string = response.body().string();
            // 可进行相关UI更新操作,但必须是在主线程中
            Log.d(TAG, String.format("response:%s", string));
        }
    }
});

可以看到多了一个post(requetBody)方法,需要传入一个RequestBody参数,RequestBody是有一个抽象类,有两个子类FormBodyMultipartBody,前者用于传输表单的数据,后者在传输表单数据的同时,还能传输文件

当然我们还可以直接创建RequestBody对象

// 传输文件
MediaType jsonType = MediaType.get("application/octet-stream");
File file = new File("typora.txt");
RequestBody requestBody = RequestBody.create(file, jsonType);


// 传输Json
MediaType jsonType = MediaType.parse("application/json; charset=utf-8");
String jsonStr = "{\"name\":\"Tom\"}";
RequestBody requestBody = RequestBody.create(jsonStr, jsonType);

作为一个网络框架,自然是可以设置超时时间的:

OkHttpClient client = new OkHttpClient.Builder()
    .callTimeout(6000, TimeUnit.MILLISECONDS)
    .connectTimeout(6000, TimeUnit.MILLISECONDS)
    .readTimeout(6000, TimeUnit.MILLISECONDS)
    .writeTimeout(6000, TimeUnit.MILLISECONDS)
    .build();

还有就是设置请求头Header:

Request request = new Request.Builder()
    .url("https://www.baidu.com/")
    .post(formBody)
    .header("Charset", "UTF-8")
    .headers(
    new Headers.Builder()
    .add("Charset", "UTF-8").build()
)
    .addHeader("Charset", "UTF-8")
    .removeHeader("Charset")
    .build();

可以看到有四个关于Header的操作方法,根据方法名也比较好理解,add/remove就是添加/移除Headerheader/headers就是把请求中的Header信息替换掉

补充

OkHttp中还有一个拦截器,先看下面的示例代码:

public class LoginInterceptor implements Interceptor {

    private final String TAG = "LoginInterceptor:OkHttp";

    @NotNull
    @Override
    public Response intercept(@NotNull Chain chain) throws IOException {

        Request request = chain.request();
        Log.d(TAG, String.format("request: \n1.%s\n2.%s\n3.%s",
                request.url(), chain.connection(), request.headers()));

        Response response = chain.proceed(request);
        Log.d(TAG, String.format("response: \n1.%s\n2.%s",
                response.request().url(), response.headers()));
        return response;
    }
}

实现拦截器必须要实现Interceptor,并实现intercept(chain)方法,可以看到需要返回Response对象,所以还不需要执行Response response = chain.proceed(request);并返回Response对象

拦截器分为应用拦截器和网络拦截器,这里借用参考文章中的图:

关系图
OkHttpClient client = new OkHttpClient.Builder()
    //.addInterceptor(new LoginInterceptor()) // 添加应用拦截器
    .addNetworkInterceptor(new LoginInterceptor()) // 添加网络拦截器
    .build();

关于OkHttp的基本使用就这些了

相关文章

网友评论

      本文标题:OkHttp的使用

      本文链接:https://www.haomeiwen.com/subject/eqeegctx.html