Android OkHttp3 基本使用

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=%E5%9B%BD%E5%BA%86%E8%8A%82%E5%BF%AB%E4%B9%90&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=%E5%9B%BD%E5%BA%86%E8%8A%82%E5%BF%AB%E4%B9%90&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

发布了100 篇原创文章 · 获赞 5 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_34760508/article/details/96429342