Android网络通讯之OkHttp

OkHttp是安卓上常用的网络请求框架,不止可以发送http请求,还可以发送socket请求等。

  • 内置了连接池,减少了请求延迟
  • 支持缓存,减少重复的网络请求
  • 支持Cookie存储
  • 支持拦截器,可以对不同的请求做拦截处理
  • 支持get、post等请求
  • 支持文件上传下载
  • 支持json请求
  • 支持同步、异步处理

官网地址:https://square.github.io/okhttp/

使用步骤

准备

1、在build.gradle中引入依赖implementation("com.squareup.okhttp3:okhttp:4.10.0")

2、在AndroidManifest.xml中添加网络请求权限

一、在安卓程序中使用

创建httpClient

OkHttpClient okHttpClient = new OkHttpClient();
1、同步get请求

安卓程序中的网络请求必须异步处理,所以另外启动了一个线程

public void doGetSync(View view) {
    new Thread(() -> {
        Request request = new Request.Builder().url("https://www.httpbin.org/get?name=test&b=123").build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            Log.d(TAG, "doGetSync: " + response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }).start();
}
2、异步get请求

调用enqueue()方法,传入回调函数

public void doGetAsync(View view) {
    Request request = new Request.Builder().url("https://www.httpbin.org/get?name=test&b=123").build();
    okHttpClient.newCall(request).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 {
            if (response.isSuccessful()) {
                Log.d(TAG, "doGetAsync: " + response.body().string());
            }
        }
    });
}
3、同步post请求

post请求必须传入一个body参数,这里传入一个formBody

public void doPostSync(View view) {
    new Thread(() -> {
        FormBody formBody = new FormBody.Builder().add("name", "test").add("b", "123").build();
        Request request = new Request.Builder().url("https://www.httpbin.org/post")
                .post(formBody).build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            Log.d(TAG, "doPostSync: " + response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }).start();
}
4、异步post请求

调用enqueue()方法,传入回调函数

public void doPostAsync(View view) {
    FormBody formBody = new FormBody.Builder().add("name", "test").add("b", "123").build();
    Request request = new Request.Builder().url("https://www.httpbin.org/post")
            .post(formBody).build();
    okHttpClient.newCall(request).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 {
            if (response.isSuccessful()) {
                Log.d(TAG, "doPostAsync: " + response.body().string());
            }
        }
    });
}

二、拦截器使用

OkHttp中有两种添加拦截器的方法

  • addInterceptor:先执行
  • addNetworkInterceptor:后执行
public class InterceptorTest {

    @Test
    public void test() throws IOException {
        OkHttpClient httpClient = new OkHttpClient.Builder()
                .addInterceptor(chain -> {
                    System.out.println("---Interceptor拦截器---");
                    Request request = chain.request().newBuilder()
                            .addHeader("os", "android")
                            .addHeader("version", "1.0").build();
                    return chain.proceed(request);
                })
                .addNetworkInterceptor(chain -> {
                    System.out.println("---NetworkInterceptor拦截器---");
                    String os = chain.request().header("os");
                    System.out.println("os = " + os);
                    return chain.proceed(chain.request());
                }).build();

        Request request = new Request.Builder().url("https://www.httpbin.org/get?name=test&b=123").build();
        Response response = httpClient.newCall(request).execute();
        System.out.println("response = " + response.body().string());
    }
}

打印输入内容:

---Interceptor拦截器---
---NetworkInterceptor拦截器---
os = android
response = {
  "args": {
    "name": "test", 
    "b": "123"
  }, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Host": "www.httpbin.org", 
    "Os": "android", 
    "User-Agent": "okhttp/4.10.0", 
    "Version": "1.0", 
    "X-Amzn-Trace-Id": "Root=1-636b6373-18b0b24d6539a83e489ab0c4"
  }, 
  "origin": "124.78.136.197", 
  "url": "https://www.httpbin.org/get?name=test&b=123"
}

三、Cookie使用

在某些网站中请求需要携带cookie,在OKHttp中提供了较好的支持

通过cookieJar方法提供cookie支持逻辑处理

本示例代码使用www.wanandroid.com的开放接口,可以自行去注册一个账号用于测试

public class CookieTest {

    @Test
    public void test() throws IOException {
        Map<String, List<Cookie>> cookies = new HashMap<>();
        OkHttpClient client = new OkHttpClient.Builder().cookieJar(new CookieJar() {
            @Override
            public void saveFromResponse(@NonNull HttpUrl httpUrl, @NonNull List<Cookie> list) {
                cookies.put(httpUrl.host(), list);
            }

            @NonNull
            @Override
            public List<Cookie> loadForRequest(@NonNull HttpUrl httpUrl) {
                List<Cookie> list = cookies.get(httpUrl.host());
                return list == null ? new ArrayList<>() : list;
            }
        }).build();
        // 登录接口
        FormBody formBody = new FormBody.Builder()
                .add("username", "xxxxx")
                .add("password", "xxxxx")
                .build();
        Request request = new Request.Builder()
                .url("https://www.wanandroid.com/user/login")
                .post(formBody)
                .build();
        Response response = client.newCall(request).execute();
        System.out.println("response1 = " + response.body().string());
        // 登录成功后,加载收藏列表
        Request request1 = new Request.Builder()
                .url("https://www.wanandroid.com/lg/collect/list/0/json")
                .build();
        response =  client.newCall(request1).execute();
        System.out.println("response2 = " + response.body().string());
    }
}

你可能感兴趣的:(android,okhttp,android)