当前位置: 首页 > news >正文

Android:OkHttp网络请求框架的使用

目录

一,OkHttp简介

二,OkHttp请求处理流程

三,OkHttp环境配置

四,OkHttp的使用

1.get网络请求

2.post上传表单数据

3.post上传json格式数据

4.文件上传

5.文件下载


一,OkHttp简介

        OkHttp是square公司推出的一款Android和Java网络请求库,是目前公认的最好用的网络请求框架,OkHttp有以下的特点:

  1. 支持Http/2,允许对同一主机的所有请求共享同一套接字;
  2. 使用连接池减少请求延时;
  3. 透明的GZIP压缩减少响应数据的大小;
  4. 缓存响应的内容,避免重复请求;

OkHttp源码地址:https://github.com/square/okhttp 

二,OkHttp请求处理流程

(1)使用OkHttp需要先创建OkHttpClient对象,可以使用构造器直接创建,也可以使用builder创建;

(2)使用Request.builder创建Request请求,用于封装要访问的网络地址Url。当进行post操作时,还需创建RequestBody用于封装请求数据,并调用Requst的post方法;

(3)通过OkHttpClient的newCall方法创建Call对象,使用同步或异步的方法发送Request请求,并接收Response响应数据;

三,OkHttp环境配置

(1)在build.gradle中添加依赖:

dependencies {
        implementation 'com.squareup.okhttp3:okhttp:3.14.9'
}

(2)在AndroidManifest.xml中添加网络访问权限:

<uses-permission android:name="android.permission.INTERNET"/> 

(3)在AndroidManifest.xml添加 android:usesCleartextTraffic="true" 解除Http访问禁制:

四,OkHttp的使用

OkHttp主要有以下功能:

  1. get,post请求文本数据;
  2. 上传文件;
  3. 下载文件;
  4. 加载图片(自动压缩图片大小);

1.get网络请求

private void visitInternet() {//1.创建HttpClient对象OkHttpClient okHttpClient = new OkHttpClient();//2.获取request对象Request.Builder builder = new Request.Builder().url("https://www.bilibili.com/");Request request = builder.build();//3.获取call对象Call call = okHttpClient.newCall(request);//4.执行网络操作(同步)try {//同步执行网络操作Response response = call.execute();String result = response.body().string();showResultOnUiThread(result);} catch (IOException e) {throw new RuntimeException(e);}
}

        注意这里使用了call的同步请求方式,会产生阻塞,所以此方法必须放在子线程中执行。如果不想放在子线程中执行的话,可以使用call的异步请求方式。

        当请求成功时call会返回Response,我们可以通过response.body()获取字符串,输入流等返回的信息。

2.post上传表单数据

        当需要上传数据时,需要创建RequestBody用于封装数据,因为我们这里上传的是表单数据,所以需要创建RequestBody的子类FormBody 。

private void postForm() {OkHttpClient okHttpClient = new OkHttpClient();//创建FormBody对象,封装数据(键值对信息)FormBody formBody = new FormBody.Builder().add("userName", "json").add("pwd", "123456").build();Request request = new Request.Builder().post(formBody).url(Host + "/servlet01").build();Call call = okHttpClient.newCall(request);//异步执行网络操作call.enqueue(new Callback() {//请求本身失败时调用@Overridepublic void onFailure(Call call, IOException e) {showResultOnUiThread("请求为空");}//请求成功时调用@Overridepublic void onResponse(Call call, Response response) throws IOException {String result = response.body().string();showResultOnUiThread(result);}});
}

        当使用call的异步请求方式时,需要重写两个方法onFailureonResponse,当请求失败时(连接失败或读写超时)调用onFailure,请求成功时调用onResponse。

        可以写一个简单的服务端来验证一下是否可以请求成功:

@WebServlet("/servlet01")
public class servlet01 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");String userName = req.getParameter("userName");String pwd = req.getParameter("pwd");if(userName == null || "".equals(userName)){resp.getWriter().write("用户名不能为空");}else if(pwd == null || "".equals(pwd)){resp.getWriter().write("密码不能为空");}else {resp.getWriter().write("欢迎:" + userName);}}
}

3.post上传json格式数据

        使用Gson需要先添加依赖:

implementation'com.google.code.gson:gson:2.10.1'

        当上传json数据时,自然需要用到RequestBody来封装json数据,同时还需用MediaType来设置数据类型(也就是我们想要上传的数据的类型)。

private void postJson() {OkHttpClient okHttpClient = new OkHttpClient();//1.创建json数据User user = new User();user.setUsername("json");user.setPwd("123456");String json = new Gson().toJson(user);//2.通过RequestBody封装json数据RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),//设置数据类型json//数据);Request request = new Request.Builder().post(requestBody).url(Host + "/servlet02").build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();String result = response.body().string();showResultOnUiThread(result);} catch (IOException e) {throw new RuntimeException(e);}
}

同样写一个简单服务端来测试一下:

@WebServlet("/servlet02")
public class servlet02 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(req.getInputStream()));String data = bufferedReader.readLine();resp.getWriter().write("json:" + data);}
}

4.文件上传

        通过OkHttp上传文件的步骤与上传json数据一致,只需更换设置的数据类型即可。因为上传的需要是安卓客户端的数据,所以我们需要先在安卓客户端添加数据。

        打开路径data/data/com.example.okhttp/files,在files目录下添加一张图片,之后就可以开始上传了。第一次打开时没有files这个目录,需要手动创建。

同时还需要给app添加访问sd卡的权限,在AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

客户端上传文件:

private void upImg() {//通过文件路径打开文件String path = getFilesDir().getAbsolutePath() +"/zj.png";File file = new File(path);OkHttpClient okHttpClient = new OkHttpClient();RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"),file);Request request = new Request.Builder().post(requestBody).url(Host + "/servlet02").build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();String result = response.body().string();showResultOnUiThread(result);} catch (IOException e) {throw new RuntimeException(e);}
}

服务端接收文件:

@WebServlet("/servlet02")
public class servlet02 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");File file = new File(filePath);ServletInputStream inputStream = req.getInputStream();FileOutputStream fileOutputStream = new FileOutputStream(file);byte[] bytes = new byte[1024];int len = -1;while((len = inputStream.read(bytes)) != -1){fileOutputStream.write(bytes, 0, len);fileOutputStream.flush();}resp.getWriter().write("上传成功!");inputStream.close();fileOutputStream.close();}
}

5.文件下载

下载文件时不需要上传数据,因此不用创建RequestBody对象,只需发送请求即可。

private void downImg() {OkHttpClient okHttpClient = new OkHttpClient();Request request = new Request.Builder().url(Host2 + "/servlet03").build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();//获取返回的输入流InputStream inputStream = response.body().byteStream();//转成bitmap数据Bitmap bitmap = BitmapFactory.decodeStream(inputStream);runOnUiThread(new Runnable() {@Overridepublic void run() {img_img.setImageBitmap(bitmap);}});} catch (IOException e) {throw new RuntimeException(e);}
}

服务端提供数据:

@WebServlet("/servlet03")
public class servlet03 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {File file = new File(filePath);ServletOutputStream outputStream = resp.getOutputStream();BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));byte[] bytes = new byte[1024];int len = -1;while((len = bufferedInputStream.read(bytes)) != -1){bufferedOutputStream.write(bytes, 0, len);}bufferedOutputStream.close();bufferedInputStream.close();}
}

相关文章:

  • 【二叉树】LeetCode.144:二叉树的前序遍历(小细节把握)
  • 今天说的什么好呢
  • 汇编原理(二)
  • STL库 —— unordered_set与unordered_map的封装
  • 5月23日学习记录
  • 002 CentOS 7.9 redis-7.2.5安装及配置
  • idea2023的git从dev分支合并到主分支master
  • AlexNet论文解析—ImageNet Classification with Deep Convolutional Neural Networks
  • AIGC-常见图像质量评估MSE、PSNR、SSIM、LPIPS、FID、CSFD,余弦相似度----理论+代码
  • 公共代理IP和独享代理IP之间的区别?
  • Java进阶学习笔记28——StringJoiner
  • python内置函数map/filter/reduce详解
  • VLAN高级特性
  • 吴恩达深度学习笔记:超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架(Hyperparameter tuning)3.4-3.5
  • SpringBoot如何实现跨域?
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 【技术性】Search知识
  • eclipse的离线汉化
  • node-glob通配符
  • Python中eval与exec的使用及区别
  • vue学习系列(二)vue-cli
  • 飞驰在Mesos的涡轮引擎上
  • 规范化安全开发 KOA 手脚架
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 聊聊hikari连接池的leakDetectionThreshold
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 中文输入法与React文本输入框的问题与解决方案
  • #HarmonyOS:Web组件的使用
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (javascript)再说document.body.scrollTop的使用问题
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (SERIES12)DM性能优化
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (第27天)Oracle 数据泵转换分区表
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (小白学Java)Java简介和基本配置
  • (一)、python程序--模拟电脑鼠走迷宫
  • (一)Docker基本介绍
  • (已解决)vscode如何选择python解释器
  • (转)创业家杂志:UCWEB天使第一步
  • .NET8 动态添加定时任务(CRON Expression, Whatever)
  • .NET企业级应用架构设计系列之结尾篇
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • .Net实现SCrypt Hash加密
  • .NET周刊【7月第4期 2024-07-28】
  • @SpringBootConfiguration重复加载报错
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [2]十道算法题【Java实现】
  • [⑧ADRV902x]: Digital Pre-Distortion (DPD)学习笔记
  • [Android]Android开发入门之HelloWorld
  • [Android]使用Android打包Unity工程
  • [AndroidStudio]_[初级]_[修改虚拟设备镜像文件的存放位置]
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作