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() {
        //请求本身失败时调用
        @Override
        public void onFailure(Call call, IOException e) {
            showResultOnUiThread("请求为空");
        }
        //请求成功时调用
        @Override
        public 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 {
    @Override
    protected 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 {
    @Override
    protected 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 {
    @Override
    protected 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() {
            @Override
            public void run() {
                img_img.setImageBitmap(bitmap);
            }
        });
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

服务端提供数据:

@WebServlet("/servlet03")
public class servlet03 extends HttpServlet {
    @Override
    protected 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();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/632961.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

淘宝api接口是什么意思?api接口申请资格是什么?

淘宝其开放性和灵活性为开发者提供了广阔的创新空间。而淘宝API接口&#xff0c;作为连接淘宝平台与外部应用的桥梁&#xff0c;发挥着至关重要的作用。那么&#xff0c;淘宝api接口是什么意思&#xff1f; 一、淘宝API接口是什么意思&#xff1f; 淘宝API接口&#xff0c;全称…

UNI-APP设置屏幕保持常亮-不熄灭屏幕

前言 最近在实际开发过程中&#xff0c;我们会发现在自己使用的app当中会根据系统无操作熄灭屏幕对于一下需要长时间保持屏幕的业务就很不友好&#xff0c;uni-app也是提供了相应方法加上代码之后-注意app端没报错-不生效就是权限问题-需要设置相对应权限-打自定义包 代码实现…

vue+springboot实现echarts数据图统计

①vue项目修改配置 安装依赖&#xff1a; npm i echarts -S 修改路由index.js&#xff1a; import Vue from vue import VueRouter from vue-router import Manager from ../views/Manager.vue // 解决导航栏或者底部导航tabBar中的vue-router在3.0版本以上频繁点击菜单报错…

【编译原理复习笔记】语法分析-补充(二义性与LR错误处理)

二义性文法的 LR 分析 每个二义性文法都不是 LR 的 但是某些二义性文法更加简短&#xff0c;描述更方便 如 I7 和 I8 具有移进归约冲突 使用优先级和结合性解决冲突 对于 I7&#xff0c;由于乘号优先级高于加号&#xff0c;所以当下一个输入符号为乘号时&#xff0c;我们优…

03-02-Vue组件之间的传值

前言 我们接着上一篇文章 03-01-Vue组件的定义和注册 来讲。 下一篇文章 04-Vue&#xff1a;ref获取页面节点–很简单 父组件向子组件传值 我们可以这样理解&#xff1a;Vue实例就是一个父组件&#xff0c;而我们自定义的组件&#xff08;包括全局组件、私有组件&#xff09;…

Java基础入门day49

day49 tomcat 启动 进入tomcat的bin目录&#xff0c;双击或者运行startup.bat文件启动tomcat 控制台最后出现服务器启动在多少毫米之内&#xff0c;代表服务器成功启动 org.apache.catalina.startup.Catalina.start Server startup in 405 ms 验证tomcat 在浏览器中输入 loca…

linux---进程通信

提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、匿名管道 进程之间的通信目的一般是来控制另一个进程。也可以用来实现数据的交流&#xff0c;还有资源共享等。 匿名管道原理&#xff1a; &#xff08;铺垫&#xff09;进程之间是具有独立性&…

超市进销存|基于SprinBoot+vue的超市进销存系统(源码+数据库+文档)

超市进销存系统 目录 基于SprinBootvue的超市进销存系统 一、前言 二、系统设计 三、系统功能设计 1 登录注册 2 管理员功能模块 3员工功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#x…

【时间复杂度和空间复杂度之间的故事】

【时间复杂度和空间复杂度之间的故事】 一.前言 二.时间复杂度定义时间复杂度的计算规则习题 三.空间复杂度定义计算方法习题空间复杂度 O(1)空间复杂度 O(n) 本文主要讲解关于时间复杂度与空间复杂度 &#x1f600;&#x1f603;&#x1f601;&#x1f601;&#x1f607;&…

桂林电子科技大学计算机工程学院、广西北部湾大学计信学院莅临泰迪智能科技参观交流

5月18日&#xff0c;桂林电子科技大学计算机工程学院副院长刘利民、副书记杨美娜、毕业班辅导员黄秀娟、广西北部湾大学计信学院院长助理刘秀平莅临广东泰迪智能科技股份有限公司产教融合实训基地参观交流。泰迪智能科技副总经理施兴、广西分公司郑廷和、梁霜、培训业务部孙学镂…

Outlook 开启smtp配置

微软 Outlook 邮箱各种服务详细信息 服务类型服务器地址端口加密方法POPoutlook.office365.com995TLSIMAPoutlook.office365.com993TLSSMTPsmtp.office365.com587STARTTLS 然而仅仅有以上信息还不够&#xff0c;需要获取服务密码 (授权码) 才能够使用 POP, IMAP, SMTP 这三种…

常见应用流量特征分析

目录 1.sqlmap 1.常规GET请求 2.通过--os-shell写入shell 3.post请求 2.蚁剑 编码加密后 3.冰蝎 冰蝎_v4.1 冰蝎3.2.1 4.菜刀 5.哥斯拉 1.sqlmap 1.常规GET请求 使用的是sqli-labs的less7 &#xff08;1&#xff09;User-Agent由很明显的sqlmap的标志&#xff0c;展…

基础常用动词,柯桥西班牙语培训

1. Ser&#xff1a;是 表示身份: Soy Ana. Soy estudiante. 我是安娜。我是一名学生。 表示属性: Es duro. 这是硬的。 表示国籍: Soy espaol, de Madrid. 我是西班牙人&#xff0c;来自马德里。 2. Estar: 是..., 在... 表示身体状况: Estoy muy cansada, necesito dormir.我很…

JMH301【亲测】5月最新整理【神鬼传奇】斗罗超变单机版175级新宠物宝宝坐骑丰富超变定制装备带完整GM命令网游单机虚拟机一键端

资源介绍&#xff1a; 是否需要虚拟机&#xff1a;是 文件大小&#xff1a;压缩包约8.6G 支持系统&#xff1a;win7、win10、win11 硬件需求&#xff1a;运行内存8G 4核及以上CPU 下载方式&#xff1a;百度网盘 内容持续更新&#xff01; 资源截图&#xff1a; 下载地址…

DataBinding viewBinding(视图绑定与数据双向绑定)简单案例 (kotlin)

先上效果&#xff1a; 4个view的文字都是通过DataBinding填充的。交互事件&#xff1a;点击图片&#xff0c;切换图片 创建项目&#xff08;android Studio 2023.3.1&#xff09; Build.gradle(:app) 引入依赖库&#xff08;完整源码&#xff09; buildFeatures { vie…

Docker访问文件权限受限问题解决

问题描述 运行项目的docker环境&#xff0c;新添加了一个数据集&#xff0c;但是数据集的访问权限受限&#xff08;Permission dinied&#xff09;&#xff0c;运行的命令如图所示 问题解决 chmod 777 xxx YYDS&#xff01;&#xff01;&#xff01;但是单纯直接运行会因为权限…

产品经理-交互说明撰写(八)

1. 交互说明 交互说明可以看做是交互设计师或者产品经理输出的最核心的”产品“交互说明面向的”用户“是下游的同事 ⇒ UI设计师、开发工程师、测试工程师 2. 基本交互形式 2.1 页面交互 2.2 元素控件交互 3. 交互说明主要包括以下3个维度 3.1 页面流程&#xff08;页面之…

OpenFeign高级用法:缓存、QueryMap、MatrixVariable、CollectionFormat优雅地远程调用

码到三十五 &#xff1a; 个人主页 微服务架构中&#xff0c;服务之间的通信变得尤为关键。OpenFeign&#xff0c;一个声明式的Web服务客户端&#xff0c;使得REST API的调用变得更加简单和优雅。OpenFeign集成了Ribbon和Hystrix&#xff0c;具有负载均衡和容错的能力&#xff…

在 Android 上存档短信:4 种方法的终极指南

概括 无论是个人对话还是专业信件&#xff0c;我们的短信收件箱很快就会因大量线程和对话而变得混乱。为了帮助管理这种过载&#xff0c;许多 Android 用户转向了归档短信这一便捷功能。在本指南中&#xff0c;我们将探讨如何在 Android 设备上存档短信的详细信息&#xff0c;…