OkHttp 作为一个优秀的开源框架,它能处理很多疑难杂症,使用非常方便,在 Android 开发中已经使用得非常广泛。
HelloWorld
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(2, TimeUnit.SECONDS) .build(); Request request = new Request.Builder() .url("http://10.50.40.53:8081/login") .addHeader("Authorization", "abcde") .method("GET", null) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG, "onFailure: " + e); } @Override public void onResponse(Call call, Response response) throws IOException { boolean success = response.isSuccessful(); Log.d(TAG, "onResponse: " + success); String responseString = response.body().string(); Log.d(TAG, "onResponse: " + responseString); runOnUiThread(new Runnable() { @Override public void run() { } }); } });
|
上面的代码使用 OkHttpClient.Builder 创建了一个 client 实例,然后使用 Request.Builder 创建一个 request 实例,该对象存储了该次请求所需要传递到服务器的信息,以及 http 请求的一些设置。通过 client.newCall 创建一个 Call 对象,该对象的 enqueue 方法被调用的时候,request 所携带的信息被传递到后台服务器。
通常一个应用中,OkHttpClient 实例是使用单例来存储,整个应用使用同一个 client 实例。
Request.Builder
使用 Request.Builder 可以快速的创建一个请求配置,比如请求方式,参数传递,添加 Header 等。
method
使用 Request.Builder 指定请求方式,有两种方式,一是使用 Request.Builder 的 method 方法,二是使用请求方式对应的方法名。
1 2 3
| builder.method("GET", null); builder.get();
|
其它请求方式 POST、DELETE、HEAD、PUT、PATCH 等都有相对应的方法;
注意:GET 请求和 HEAD 请求,如果使用 method 来指定,则第二个参数必须为 null。
使用 addHeader 方法可以为请求添加请求头信息,也可以使用 header 或者 headers 方法指定请求头。
RequestBody
在使用 POST、DELETE 等请求时,需要使用 RequestBody 来传递参数到后台服务器,RequestBody 是一个抽象类,可以使用 FormBody 来快速创建一个参数信息表单。
1 2 3
| RequestBody body = new FormBody.Builder() .addEncoded("username", "ccf") .build();
|
这样创建的一个 FormBody 表单对象,在请求的时候就会被传递到服务器。
Upload-File
文件上传也是一个 POST 请求,不过此时需要使用 RequestBody,而不能直接使用 FormBody。
比如上传一个 txt 文件
1 2 3 4
| File file = ...; RequestBody.Builder builder = new RequestBody.Builder(); builder.post(RequestBody.create(MediaType.parse("text/plain"), file));
|
相对应的,如果上传其它文件,则把 MediaType 更改成对应的 type 即可。
File-Download
文件下载和普通的 GET 请求在使用上没有区别,只是在 Callback#onResponse方法处理上,需要做一些调整。
1 2 3 4 5 6
| @Override public void onResponse(Call call, Response response) { InputStream inputStream = response.body().byteStream(); saveFile(inputStream); }
|
MultipartBody
有时在上传文件的同时还需要传其他参数,此时可以使用 MultipartBody 上传文件和参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| File file = ...; RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("title", "Awesome picture") .addFormDataPart("image", "awesome_picture.jpg", RequestBody.create(MediaType.parse("image/*"), file)) .build(); Request request = new Request.Builder() .header("Authorization", "Client-ID " + "...") .url(...) .post(requestBody) .build();
|
OkHttpClient.Builder
client 所需要的所有配置,都可以通过 Builder 来快速创建配置。
timeout & cache
1 2 3 4 5 6 7
| File sdcache = getExternalCacheDir(); int cacheSize = 10 * 1024 * 1024; OkHttpClient.Builder builder = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
|
通过上面的三个 xxxTimeout 方法可以设置相应的超时时间,以及缓存文件存放位置。
Other
- retryOnConnectionFailure : 设置失败重连;
- addNetworkInterceptor : 添加拦截器,可以在拦截器中添加进行 debug 输入,添加请求头等;
Call
Call 对象用于发起请求,当一个请求发起之后,可以使用 cancel() 方法取消该请求。
发起请求有两种方式:
- enqueue(Callback) 发起异步请求,使用网络请求线程
- execute 发起同步请求,使用当前代码所在的线程