Android OkHttp3 基本使用

it2022-05-05  163

OkHttp的优点

支持HTTP2/SPDY(SPDY是Google开发的基于TCP的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。)socket自动选择最好路线,并支持自动重连,拥有自动维护的socket连接池,减少3 握手次数,减少了请求延迟,共享Socket,减少对服务器的请求次数。基于Headers的缓存策略减少重复的网络请求。拥有Interceptors轻松处理请求与响应(自动处理GZip压缩

基本使用

添加依赖 compile 'com.squareup.okhttp3:okhttp:3.7.0' compile 'com.squareup.okio:okio:1.12.0' 添加网络权限 <uses-permission android:name="android.permission.INTERNET"/> 发送一个请求一般需要五步

1 创建一个OkHttpClient对象,可以设置,超时时间,拦截器等

OkHttpClient mOkHttpClient = new OkHttpClient.Builder() .connectTimeout(60, TimeUnit.SECONDS) .writeTimeout(60, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .addNetworkInterceptor(logInterceptor) .build();

2 创建一个Request对象,通常设置:url,请求方法,设置请求头等,如果是post方法,还需要构建一个RequestBody,上传文件,字符串,表单等都需要通过不同的RequestBody去构建

Request request = new Request.Builder() .url(url) .post(RequestBody) .build();

3 通过OkHttpClient和Request获取一个Call对象,Call对象有execute()和cancel()等方法

Call call = mOkHttpClient.newCall(request);

4 执行请求,可以异步请求,也可以同步请求

//同步请求 Response execute = call.execute(); //异步请求 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { }

5 处理结果

onResponse回调有一个参数是response, 如果我们想获得返回的是字符串,可以通过response.body().string()获取; 如果希望获得返回的二进制字节数组,则调用response.body().bytes(); 如果你想拿到返回的inputStream,则调response.body().byteStream(),有inputStream我们就可以通过IO的方式写文件

打印完整的okhttp网络请求和响应消息

我们请求网络一般都需要拿到我们发送的参数和返回的参数,来确认问题,拿到这些的参数,需要三部

添加依赖 implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0' 继承拦截器 public class HttpLogger implements HttpLoggingInterceptor.Logger { @Override public void log(String message) { Log.d("mmmhttp", message); } } 设置拦截器 HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(new HttpLogger()); logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient mOkHttpClient = new OkHttpClient.Builder() .connectTimeout(60, TimeUnit.SECONDS) .writeTimeout(60, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .addNetworkInterceptor(logInterceptor) .build();

通过上方三部就可以拿到对应的参数了

07-18 14:18:55.016 6391-6413/com.baidu.bpit.aibaidu.cachevoice D/mmmhttp: --> GET http://tts.baidu.com/text2audio?idx=1&tex=国庆节快乐&cuid=xieyan&cod=2&lan=zh&ctp=1&pdt=1&pit=9 http/1.1 Host: tts.baidu.com Connection: Keep-Alive Accept-Encoding: gzip User-Agent: okhttp/3.7.0 --> END GET 07-18 14:18:55.073 6391-6413/com.baidu.bpit.aibaidu.cachevoice D/mmmhttp: <-- 200 OK http://tts.baidu.com/text2audio?idx=1&tex=国庆节快乐&cuid=xieyan&cod=2&lan=zh&ctp=1&pdt=1&pit=9 (56ms) Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Origin: * Cache-Control: max-age=36000 Connection: keep-alive Content-Length: 3456 Content-Type: audio/mp3 Date: Thu, 18 Jul 2019 06:18:54 GMT P3p: CP=" OTI DSP COR IVA OUR IND COM " Server: nginx/1.8.0 Set-Cookie: BAIDUID=913C2C4A2038EC7D9B22A8FC7AC3AD53:FG=1; expires=Fri, 17-Jul-20 06:18:54 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1 07-18 14:18:55.074 6391-6413/com.baidu.bpit.aibaidu.cachevoice D/mmmhttp: <-- END HTTP (binary 3456-byte body omitted)

异步Get请求

省略了创建OkHttpClient的步骤,因为跟上方一样

//2.创建Request对象,设置一个url地址(百度地址),设置请求方式。 Request request = new Request.Builder() .url("http://www.baidu.com") .get() .build(); Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } });

Post提交键值对

RequestBody requestBody = new FormBody.Builder() .add("name","zhangqilu") .add("age","25").build(); //3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入 Request request = new Request.Builder() .url("url") .post(requestBody) .build(); //4.创建一个call对象,参数就是Request请求对象 Call call = mOkHttpClient.newCall(request); //5.请求加入调度,重写回调方法 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } });

这是一个post方法,需要构建一个ReqestBody,这里由于要传入key-value,使用的是FormBody是RequestBody子类

POST请求提交字符串

MediaType mediaType = MediaType.parse("application/json; charset=utf-8");//"类型,字节码" //字符串 String value = "{username:admin;password:admin}"; //2.通过RequestBody.create 创建requestBody对象 RequestBody requestBody =RequestBody.create(mediaType, value); //3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入 Request request = new Request.Builder() .url("url") .post(requestBody) .build(); //4.创建一个call对象,参数就是Request请求对象 Call call = mOkHttpClient.newCall(request); //5.请求加入调度,重写回调方法 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } });

POST请求上传文件

//上传的图片 File file = new File(Environment.getExternalStorageDirectory(), "zhuangqilu.png"); //2.通过RequestBody.create 创建requestBody对象,application/octet-stream 表示文件是任意二进制数据流 RequestBody requestBody =RequestBody.create(MediaType.parse("application/octet-stream"), file); //3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入 Request request = new Request.Builder() .url("url") .post(requestBody) .build(); //4.创建一个call对象,参数就是Request请求对象 Call call = mOkHttpClient.newCall(request); //5.请求加入调度,重写回调方法 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } });

GET请求下载文件

//2.创建Request对象,设置一个url地址(百度地址),设置请求方式。 Request request = new Request.Builder() .url(url) .get() .build(); //3.创建一个call对象,参数就是Request请求对象 Call call = mOkHttpClient.newCall(request); //4.请求加入调度,重写回调方法 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.d("mmm", "onFailure: " + call.toString()); } @Override public void onResponse(Call call, Response response) throws IOException { //拿到字节流 InputStream is = response.body().byteStream(); Log.d("mmm数据", is.available() + "/"); int len = 0; //设置下载图片存储路径和名称 File file = new File(yunyinDir, name + ".mp3"); if (!file.exists()) { file.createNewFile(); } FileOutputStream fos = new FileOutputStream(file); byte[] buf = new byte[128]; while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); Log.d("mmm", "onResponse: " + len); } Log.d("mmm", "下载完毕"); fos.flush(); fos.close(); is.close(); } });

POST请求上传Multipart文件

有时候我们需要同时上传文件和其他类型字段,这其实就是一个表单,这里我们用MuiltipartBody来构建,他是RequestBody的一个子类

//上传的图片 File file = new File(Environment.getExternalStorageDirectory(), "zhuangqilu.png"); //2.通过new MultipartBody build() 创建requestBody对象, RequestBody requestBody = new MultipartBody.Builder() //设置类型是表单 .setType(MultipartBody.FORM) //添加数据 .addFormDataPart("username","zhangqilu") .addFormDataPart("age","25") .addFormDataPart("image","zhangqilu.png", RequestBody.create(MediaType.parse("image/png"),file)) .build(); //3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入 Request request = new Request.Builder().url("url").post(requestBody).build(); //4.创建一个call对象,参数就是Request请求对象 Call call = mOkHttpClient.newCall(request); //5.请求加入调度,重写回调方法 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } });

参考:https://blog.csdn.net/zhangqiluGrubby/article/details/71480546


最新回复(0)