您当前的位置: 首页 >  网络

【Android -- 网络请求】网络请求(Okhttp)

发布时间:2017-08-08 14:09:56 ,浏览量:5

在这里插入图片描述

前言

目前大量流行库都以 OkHttp 作为底层网络请求框架或提供支持,比如:Retrofit、Glide、Fresco、Moshi、Picasso 等。 常用的状态码:

  • 100~199:指示信息,表示请求已接收,继续处理
  • 200~299:请求成功,表示请求已被成功接收、理解
  • 300~399:重定向,要完成请求必须进行更进一步的操作
  • 400~499:客户端错误,请求有语法错误或请求无法实现
  • 500~599:服务器端错误,服务器未能实现合法的请求
特点
  • 同时支持 Http1.1 和 Http2.0
  • 同时支持同步与异步请求;
  • 同时具备 Http 与 WebSocket 功能;
  • 拥有自动维护的 socket 连接池,减少握手次数;
  • 拥有队列线程池,轻松写并发;
  • 拥有 Interceptors(拦截器),轻松处理请求与响应额外需求。
使用
  1. 在 AndroidManifest.xml 中添加网络访问权限:
<uses-permission android:name="android.permission.INTERNET"/> 
  1. 在 app/build.gradle 的 dependencies 中添加如下依赖:
implementation("com.squareup.okhttp3:okhttp:4.9.3") implementation("com.squareup.okhttp3:logging-interceptor:4.9.3") 
GET 请求 同步 GET 请求

同步 GET 请求是指一直等待 http 请求,直到返回了响应。在这之间会阻塞线程,所以同步请求不能在 Android 的主线程中执行,否则会报 NetworkMainThreadException.

String BASE_URL = "http://wwww.baidu.com"; //1.新建OKHttpClient客户端 OkHttpClient okHttpClient = new OkHttpClient(); //2. 新建一个Request对象 final Request request = new Request.Builder() .url(BASE_URL) .build(); final Call call = okHttpClient.newCall(request); new Thread(new Runnable() { @Override public void run() { try { //3.Response为 OKHttp 中的响应 Response response = call.execute(); Log.d(TAG, "run: " + response.body().string()); } catch (IOException e) { e.printStackTrace(); } } }).start(); 
异步 GET 请求

异步 GET 请求是指在另外的工作线程中执行 http 请求,请求时不会阻塞当前的线程,所以可以在 Android 主线程中使用。

String BASE_URL = "http://wwww.baidu.com"; //1.新建OKHttpClient客户端 OkHttpClient okHttpClient = new OkHttpClient(); //2. 新建一个Request对象 final Request request = new Request.Builder() .url(BASE_URL) .build(); final Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { Log.d(TAG, "onResponse: " + response.body().string()); } @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { Log.d(TAG, "onFailure: "); } }); 

说明:无论是同步还是异步请求,接收到的 response 结果都是在子线程中,onResponse、onFailure 的回调是在子线程中的,我们需要切换到主线程才能操作 UI 控件。

POST 请求 POST 方式提交 String
MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8"); String requestBody = "I am Kevin."; 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 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()); } @Override public void onFailure(Call call, IOException e) { Log.d(TAG, "onFailure: " + e.getMessage()); } }); 
POST 方式提交流
RequestBody requestBody = new RequestBody() { @Nullable @Override public MediaType contentType() { return MediaType.parse("text/x-markdown; charset=utf-8"); } @Override public void writeTo(BufferedSink sink) throws IOException { sink.writeUtf8("I am Kevin."); } }; Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(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()); } }); 
POST 提交文件
MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8"); OkHttpClient okHttpClient = new OkHttpClient(); File file = new File("test.md"); Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(RequestBody.create(mediaType, file)) .build(); 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()); } }); 
POST 方式提交表单
OkHttpClient okHttpClient = new OkHttpClient(); RequestBody requestBody = new FormBody.Builder() .add("search", "Jurassic Park") .build(); Request request = new Request.Builder() .url("https://en.wikipedia.org/w/index.php") .post(requestBody) .build(); 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()); } }); 
拦截器-interceptor 简单实例

需求:监控 App 通过 OkHttp 发出的所有原始请求,以及整个请求所耗费的时间。

  1. 自定义 LoggingInterceptor.java
public class LoggingInterceptor implements Interceptor { private static final String TAG = "LoggingInterceptor"; @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); long startTime = System.nanoTime(); Log.d(TAG, String.format("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers())); Response response = chain.proceed(request); long endTime = System.nanoTime(); Log.d(TAG, String.format("Received response for %s in %.1fms%n%s", response.request().url(), (endTime - startTime) / 1e6d, response.headers())); return response; } } 
  1. 使用
OkHttpClient okHttpClient = 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(); 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 { ResponseBody body = response.body(); if (body != null) { Log.d(TAG, "onResponse: " + response.body().string()); body.close(); } } }); 
  1. 打印日志
Sending request http://www.publicobject.com/helloworld.txt on null User-Agent: OkHttp Example Received response for https://publicobject.com/helloworld.txt in 1265.9ms Server: nginx/1.10.0 (Ubuntu) Date: Wed, 28 Mar 2018 08:19:48 GMT Content-Type: text/plain Content-Length: 1759 Last-Modified: Tue, 27 May 2014 02:35:47 GMT Connection: keep-alive ETag: "5383fa03-6df" Accept-Ranges: bytes
关注
打赏
1688896170
查看更多评论

暂无认证

  • 5浏览

    0关注

    109478博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.4001s