小工具知识网

当前位置: 首页 > 行业知识 > Android:OkHttp网络请求框架的使用

行业知识

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

2026-11-10 07:54:43 来源:互联网转载

目录

一,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中添加网络访问权限:

 

(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的异步请求方式时,需要重写两个方法onFailure和onResponse,当请求失败时(连接失败或读写超时)调用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中添加:

客户端上传文件:

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();    }}

上一篇:揭秘QQ源码与云端宝藏,探寻百度云中的神秘奥秘!

下一篇:揭秘微赞直播免费开播秘籍,轻松开启直播之旅!