springboot

OKHttp3 基本用法

2018-10-23  本文已影响0人  KT_11

1 简介

优点 (版本一)
优点 (版本二)

1)支持http2,对一台机器的所有请求共享同一个socket
2)内置连接池,支持连接复用,减少延迟
3)支持透明的gzip压缩响应体
4)通过缓存避免重复的请求
5)请求失败时自动重试主机的其他ip,自动重定向
6)好用的API

功能

2 基本使用

首先记得在build.gradle 和 配置文件分别加上依赖 和 网络权限

    compile 'com.squareup.okhttp3:okhttp:3.8.0'
    compile 'com.squareup.okio:okio:1.12.0'

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

2-1 异步Get请求

异步GET请求的4个步骤:
  1. 创建OkHttpClient对象
  2. 通过Builder模式创建Request对象,参数必须有个url参数,可以通过Request.Builder设置更多的参数比如:header、method等
  3. 通过request的对象去构造得到一个Call对象,Call对象有execute()和cancel()等方法。
  4. 以异步的方式去执行请求,调用的是call.enqueue,将call加入调度队列,任务执行完成会在Callback中得到结果。
注意事项:
实例:

我新建了一个活动,并在布局里放入一个按钮,点击就会开始执行网络请求

    private void getRequest() {
        //1.创建OkHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        //2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
        Request request = new Request.Builder().url("http://www.baidu.com").method("GET",null).build();
        //3.创建一个call对象,参数就是Request请求对象
        Call call = okHttpClient.newCall(request);
        //4.请求加入调度,重写回调方法
        call.enqueue(new Callback() {
            //请求失败执行的方法
            @Override
            public void onFailure(Call call, IOException e) {
            }
            //请求成功执行的方法
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String data = response.body().string();
                Log.d("response",data);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //更新UI
                    }
                });
            }
        });
    }

2-2 同步Get请求 (较少用)

        //1.创建OkHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        //2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
        Request request = new Request.Builder().url("http://www.baidu.com").method("GET",null).build();
        //3.创建一个call对象,参数就是Request请求对象
        Call call = okHttpClient.newCall(request);
        //4.同步调用会阻塞主线程,这边在子线程进行
        new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //同步调用,返回Response,会抛出IO异常
                        Response response = call.execute();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

2-3 异步POST——键值对

private void postAsynHttp() {
     mOkHttpClient=new OkHttpClient();
     RequestBody formBody = new FormBody.Builder()
             .add("size", "10")
             .build();
     Request request = new Request.Builder()
             .url("http://api.1-blog.com/biz/bizserver/article/list.do")
             .post(formBody)
             .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 {
             String str = response.body().string();
             runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
                     Toast.makeText(getApplicationContext(), "请求成功", Toast.LENGTH_SHORT).show();
                 }
             });
         }
     });
 }

2-4 异步POST——上传文件

       // step 1: 创建 OkHttpClient 对象
        OkHttpClient okHttpClient = new OkHttpClient();

        //step 2:创建 RequestBody 以及所需的参数
        //2.1 获取文件
        File file = new File(Environment.getExternalStorageDirectory() + "test.txt");
        //2.2 创建 MediaType 设置上传文件类型
        MediaType MEDIATYPE = MediaType.parse("text/plain; charset=utf-8");
        //2.3 获取请求体
        RequestBody requestBody = RequestBody.create(MEDIATYPE, file);

        //step 3:创建请求
        Request request = new Request.Builder().url("http://www.baidu.com")
                .post(requestBody)
                .build();

        //step 4 建立联系
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 请求失败
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // 请求成功
            }
        });
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

2-5 异步Get请求——下载文件

 private void downAsynFile() {
     mOkHttpClient = new OkHttpClient();
     String url = "http://img.my.csdn.net/uploads/201603/26/1458988468_5804.jpg";
     Request request = new Request.Builder().url(url).build();
     mOkHttpClient.newCall(request).enqueue(new Callback() {
         @Override
         public void onFailure(Call call, IOException e) {
         }
         @Override
         public void onResponse(Call call, Response response) {
             InputStream inputStream = response.body().byteStream();
             FileOutputStream fileOutputStream = null;
             try {
                 fileOutputStream = new FileOutputStream(new File("/sdcard/123.jpg"));
                 byte[] buffer = new byte[2048];
                 int len = 0;
                 while ((len = inputStream.read(buffer)) != -1) {
                     fileOutputStream.write(buffer, 0, len);
                 }
                 fileOutputStream.flush();
             } catch (IOException e) {
                 e.printStackTrace();
            }
            Log.d("123", "文件下载成功");
        }
    });
}

2-6 异步上传Multipart文件

【待补充】其实这种需求我在实际开发中暂时没有遇到过,也不是很理解

        //1.创建OkHttpClient对象
        OkHttpClient  okHttpClient = new OkHttpClient();
        //上传的图片
        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 = okHttpClient.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 {
            }
        });

3 其他配置

3-1 设置超时时间和缓存

File sdcache = getExternalCacheDir();
int cacheSize = 10 * 1024 * 1024;
OkHttpClient.Builder builder = new OkHttpClient.Builder()
        .connectTimeout(15, TimeUnit.SECONDS)
        .writeTimeout(20, TimeUnit.SECONDS)
        .readTimeout(20, TimeUnit.SECONDS)
        .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
OkHttpClient mOkHttpClient=builder.build();

3-2 添加请求头

            Request.Builder builder = new Request.Builder().url(url);
            builder.addHeader("X-UA","android");  

3-3 取消请求

自己主动取消的错误的 java.net.SocketException: Socket closed
超时的错误是 java.net.SocketTimeoutException
网络出错的错误是java.net.ConnectException: Failed to connect to xxxxx
call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if(e.toString().contains("closed")) {
                 //如果是主动取消的情况下
                }else{
                  //其他情况下
            }
          }

参考

http://www.cnblogs.com/chenxibobo/p/9585760.html
https://www.jianshu.com/p/b74466039b84
http://liuwangshu.cn/application/network/6-okhttp3.html
https://www.cnblogs.com/jianyungsun/p/6648390.html
https://www.zhihu.com/question/46147227

上一篇 下一篇

猜你喜欢

热点阅读