赞
踩
想要使用retrofit2或者Okgo等网络框架,熟悉并且掌握Okhttp3是很有必要的。HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽。OkHttp是一个高效的HTTP客户端,它有一下特性:
首先在清单文件声明internet访问权限,然后导入依赖:
implementation("com.squareup.okhttp3:okhttp:4.2.2")
步骤如下:
- String url = "http://wwww.baidu.com";
- OkHttpClient okHttpClient = new OkHttpClient();
- final Request request = new Request.Builder()
- .url(url)
- .get()//默认就是GET请求,可以不写
- .build();
- Call call = okHttpClient.newCall(request);
- call.enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- Log.d(TAG, "onFailure: ");
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- Log.d(TAG, "onResponse: " + response.body().string());
- }
- });

步骤如下:
- MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
- String requestBody = "hello kitty";
- Request request = new Request.Builder()
- .url("https://api.github.com/markdown/raw")
- .post(RequestBody.create(mediaType, requestBody))
- .build();
- OkHttpClient okHttpClient = new OkHttpClient();
- okHttpClient.newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- Log.d(TAG, "onFailure: " + e.getMessage());
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- Log.d(TAG, response.protocol() + " " +response.code() + " " + response.message());
- Headers headers = response.headers();
- for (int i = 0; i < headers.size(); i++) {
- Log.d(TAG, headers.name(i) + ":" + headers.value(i));
- }
- Log.d(TAG, "onResponse: " + response.body().string());
- }
- });

同步与异步请求的区别在于同步请求是提交请求之后会在同一个线程等待请求结果,是一个耗时操作,所以只能放在子线程中来执行,并且通过call.execute()来提交同步请求。
- String url = "http://wwww.baidu.com";
- OkHttpClient okHttpClient = new OkHttpClient();
- final Request request = new Request.Builder()
- .url(url)
- .build();
- final Call call = okHttpClient.newCall(request);
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- Response response = call.execute();//需要放在子线程中
- Log.d(TAG, "run: " + response.body().string());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }).start();

Application Interceptor
拦截器主要在两个地方使用,一个作为全局变量使用,也叫Application Interceptor,通过OkHttpClient.Builder() .addInterceptor()传入
- OkHttpClient client = new OkHttpClient.Builder()
- .addInterceptor(new LoggingInterceptor())
- .build();
-
- Request request = new Request.Builder()
- .url("http://www.publicobject.com/helloworld.txt")
- .header("User-Agent", "OkHttp Example")
- .build();
-
- Response response = client.newCall(request).execute();
- response.body().close();
上面调用的是日志拦截器,拦截器会被调用一次,并通过chain.procced()来接收响应数据。
- class LoggingInterceptor implements Interceptor {
- @Override public Response intercept(Interceptor.Chain chain) throws IOException {
- Request request = chain.request();
-
- long t1 = System.nanoTime();
- logger.info(String.format("Sending request %s on %s%n%s",
- request.url(), chain.connection(), request.headers()));
-
- Response response = chain.proceed(request);
-
- long t2 = System.nanoTime();
- logger.info(String.format("Received response for %s in %.1fms%n%s",
- response.request().url(), (t2 - t1) / 1e6d, response.headers()));
-
- return response;
- }
- }

拦截器响应结果
- INFO: Sending request http://www.publicobject.com/helloworld.txt on null
- User-Agent: OkHttp Example
-
- INFO: Received response for https://publicobject.com/helloworld.txt in 1179.7ms
- Server: nginx/1.4.6 (Ubuntu)
- Content-Type: text/plain
- Content-Length: 1759
- Connection: keep-alive
可以看到发送请求和接收请求的url是不一样的,这是因为Okhttp会自动根据发送的url做重定向。
Network Interceptors
注册网络拦截器与上面的方法相似,调用addNetworkInterceptor()
- OkHttpClient client = new OkHttpClient.Builder()
- .addNetworkInterceptor(new LoggingInterceptor())
- .build();
-
- Request request = new Request.Builder()
- .url("http://www.publicobject.com/helloworld.txt")
- .header("User-Agent", "OkHttp Example")
- .build();
-
- Response response = client.newCall(request).execute();
- response.body().close();
这里的拦截器调用两次,一次初始化请求http://www.publicobject.com/helloworld.txt,另外一次重定向为https://publicobject.com/helloworld.txt.
- INFO: Sending request http://www.publicobject.com/helloworld.txt on Connection{www.publicobject.com:80, proxy=DIRECT hostAddress=54.187.32.157 cipherSuite=none protocol=http/1.1}
- User-Agent: OkHttp Example
- Host: www.publicobject.com
- Connection: Keep-Alive
- Accept-Encoding: gzip
-
- INFO: Received response for http://www.publicobject.com/helloworld.txt in 115.6ms
- Server: nginx/1.4.6 (Ubuntu)
- Content-Type: text/html
- Content-Length: 193
- Connection: keep-alive
- Location: https://publicobject.com/helloworld.txt
-
- INFO: Sending request https://publicobject.com/helloworld.txt on Connection{publicobject.com:443, proxy=DIRECT hostAddress=54.187.32.157 cipherSuite=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA protocol=http/1.1}
- User-Agent: OkHttp Example
- Host: publicobject.com
- Connection: Keep-Alive
- Accept-Encoding: gzip
-
- INFO: Received response for https://publicobject.com/helloworld.txt in 80.9ms
- Server: nginx/1.4.6 (Ubuntu)
- Content-Type: text/plain
- Content-Length: 1759
- Connection: keep-alive

网络请求包含更多的数据,包括显示Accept-Encoding: gzip,这是Okhttp对于压缩响应数据的的支持。
Application Interceptor和Network Interceptors之间的异同之处
Application Interceptor
Network Interceptors
Okhttp github地址:https://github.com/square/okhttp
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。