OkHttp的使用

概述

OkHttp是一款优秀的HTTP框架,它支持get请求和post请求,支持基于Http的文件上传和下载,支持加载图片,支持下载文件透明的GZIP压缩,支持响应缓存避免重复的网络请求,支持使用连接池来降低响应延迟问题。

OkHttp官网地址:http://square.github.io/okhttp/

OkHttp GitHub地址:https://github.com/square/okhttp

使用介绍

1.使用前的准备工作

配置gradle

在AndroidStudio中使用不需要下载jar包,直接添加依赖即可: 

 

compile 'com.squareup.okhttp3:okhttp:3.10.0'

2.GET异步请求

这种方式的好处是不用开启子线程,但是回调方法是在子线程中,所以更新UI还是要在子线程中,示例代码如下:

 

//1.拿到OkHttpClient的对象
OkHttpClient okHttpClient=new OkHttpClient();
//2.构造Request
Request request=new Request.Builder().get().url("https://blog.csdn.net/wen_haha").build();
//3.将Request封装为Call
//4.执行call
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {

    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        final String result = response.body().string();
        L.e(result);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mTvGetResult.setText(result);
            }
        });
    }
});

其基本步骤就是创建OkHttpClient、Request和Call,最后调用Call的enqueue()方法。如果想要调用同步GET请求,可以调用Call的execute方法。

3.异步POST请求

 OkHttp3异步POST请求和OkHtto2.x有一些区别,就是没有FormEncodingBuilder这个类,替代它的是功能更强大的FormBody。我这里访问是我自己写的服务端,示例代码如下:

 

Request.Builder builder=new Request.Builder();
//构造RequestBody
RequestBody formBody=new FormBody.Builder().add("username", "jwj").add("password", "123").build();
Request request = builder.url(mUrl + "login").post(formBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {

    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        final String result = response.body().string();
        L.e(result);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mTvGetResult.setText(result);
            }
        });
    }
});

异步POST请求和异步GET请求很类似,只是多了用FormBody来封装请求的参数,并传递给Request

4.异步上传文件

上传文件本身也是一个POST,在上传之前需要定义上传文件的类型。示例代码如下:

 

File file=new File(Environment.getExternalStorageDirectory(),"123456.txt");
L.e(file.getAbsolutePath().toString());
if (!file.exists()){
    L.e("不存在!");
    return;
}
//application/octet-stream
RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
Request.Builder builder=new Request.Builder();
Request request = builder.url(mUrl + "postFile").post(requestBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {

    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        final String result = response.body().string();
        L.e(result);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mTvGetResult.setText(result);
            }
        });
    }
});

注意:上传文件涉及到权限问题,在6.0以后需要手动开启运行权限,不明白的可以去看我的关于运行权限的那篇博客。

MediaType.parse()就是定义文件类型,如果不知道怎么写,可以去http://www.w3school.com.cn/media/media_mimeref.asp查一下。如果想要改成同步上传文件,只要调用OkHttpClient.newCall(request).execute()就可以了。

5.异步下载文件

在OKHttp中并没有提供下载文件的功能,但是在Response中可以获取流对象,有了流对象我们就可以自己实现文件的下载。这段代码需要写在onResponse()中,示例代码如下:

 

OkHttpClient okHttpClient=new OkHttpClient();
Request request=new Request.Builder().get().url("http://img.lanrentuku.com/img/allimg/1707/14988864745279.jpg").build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {

    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        InputStream is = response.body().byteStream();
        final Bitmap bitmap = BitmapFactory.decodeStream(is);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mIvPhoto.setImageBitmap(bitmap);
            }
        });
    }
});

我这是通过Get请求下载了网络上的一张照片,并没有通过裁剪压缩,直接就展示在ImageView中,但在真实的项目中,如果图片过大,可能要经过裁剪,压缩。

6.异步上传Multipart文件

 

上传文件的时候,有时候还需要上传其他类型的字段,OkHttp通过MultipartBody来实现,示例代码如下:

File file=new File(Environment.getExternalStorageDirectory(),"123456.png");
L.e(file.getAbsolutePath().toString());
if (!file.exists()){
    L.e("不存在!");
    return;
}
MultipartBody.Builder multipartBuilder=new MultipartBody.Builder();
RequestBody requestBody= multipartBuilder.setType(MultipartBody.FORM)
        .addFormDataPart("username", "jwj")//1
        .addFormDataPart("password", "123456")
        .addFormDataPart("mPhoto", "jwj.png", RequestBody.create(MediaType.parse("application/octet-stream"), file))//2
        .build();
CountingRequestBody countingRequestBody=new CountingRequestBody(requestBody, new CountingRequestBody.Listener() {
    @Override
    public void onRequestProgress(long byteWrited, long contentLength) {
        L.e(byteWrited+"/"+contentLength);
    }
});
Request.Builder builder=new Request.Builder();
Request request = builder.url(mUrl + "upLoadInfo").post(countingRequestBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {

    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        final String result = response.body().string();
        L.e(result);
    }
});

首先我们要定义上传文件的类型。上面注释1是我们常见的key-value形式的参数上传,注释2则是上传表单。addFormDataPart方法的第一个参数是key值,第二个参数是上传文件的名字,第三个参数是需要上传的文件。

7.取消请求

使用call.cancel()可以立即停止一个正在执行的call,不管同步还是异步的call都可以取消,也可以通过tag来同时取消多个请求。示例代码如下:

 

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
final Request request = new Request.Builder()
        .url("http://www.baidu.com")
        .cacheControl(CacheControl.FORCE_NETWORK)
        .build();
Call call = null;
call = okHttpClient.newCall(request);
final Call finalCall = call;
//100毫秒后取消call
executor.schedule(new Runnable() {
    @Override
    public void run() {
        finalCall.cancel();
    }
}, 1, TimeUnit.MILLISECONDS);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {

    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (null != response.cacheResponse()) {
            String str = response.cacheResponse().toString();
            L.e("cache---" + str);
        } else {
            String str = response.networkResponse().toString();
            L.e("network---" + str);
        }
    }
});

9.设置超时时间和缓存

OkHttp3可以通过OkHttpClient.Builder来设置超时时间和缓存。通过builder配置好OkHttpClient后用builder.build()来返回OkHttpClient。示例代码如下:

 

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 = builder.build();

总结:

OkHttp的简单使用就已经说完了,但是如果每次都请求网络都需要写重复的代码,有时候我们需要对OkHttp进行封装一下,使OkHttp能够更加方便的使用,更加具有拓展性。我们下一篇博客就来讲解一下OkHttp的封装。

Demo

CSDN:https://download.csdn.net/download/wen_haha/10540745

Github:https://github.com/kongkongdaren/OkHttpDemo

 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值