主要可以干什么:
- 一般的get请求
- 一般的post请求
- 基于Http的文件上传
- 文件下载
- 加载图片
- 支持请求回调,直接返回对象、对象集合
- 支持session的保持
使用在build中加上:
1,compile 'com.squareup.okhttp:okhttp:2.4.0'
使用教程:
1,get请求
//创建OKhttpclient对象
OKHttpClient mOKhttpclient = new OkHttpClient();
//创建一个request
final Request request = new Request.Builder()
.url(“url”).build();
//创建一个call
Call call = mOKhttpclient.newCall(request);
//请求加入调度
call.enqueue(new Callback(){
public void onFailure(Request request, IOException e){}
public void onResponse(final Response response)throws IOException{}
});
- 以上就是发送一个get请求的步骤,首先构造一个Request对象,参数最起码有个url,当然你可以通过Request.Builder设置更多的参数比如:header、method等。
- 然后通过request的对象去构造得到一个Call对象,类似于将你的请求封装成了任务,既然是任务,就会有execute()和cancel()等方法。
- 最后,我们希望以异步的方式去执行请求,所以我们调用的是call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。
看到这,你会发现,整体的写法还是比较长的,所以封装肯定是要做的,不然每个请求这么写,得累死。
ok,需要注意几点:
- onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()
看到这,你可能会奇怪,竟然还能拿到返回的inputStream,看到这个最起码能意识到一点,这里支持大文件下载,有inputStream我们就可以通过IO的方式写文件。不过也说明一个问题,这个onResponse执行的线程并不是UI线程。的确是的,如果你希望操作控件,还是需要使用handler等,例如: - 我们这里是异步的方式去执行,当然也支持阻塞的方式,上面我们也说了Call有一个execute()方法,你也可以直接调用call.execute()通过返回一个Response。
(二) Http Post 携带参数
Request request = buildMultipartFormRequest(url,
new File[]{file},new String[]{fileKey},null);
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add(“username”,”is么”);
Request request = new Request.Builder().url(url).post(builder.build()).build();
mOKHttpclient.newCall(request).enqueue(new Callback(){});
(三)基于Http的文件上传
可以构造RequestBody的Builder,叫做MultipartBuilder。当我们需要做类似于表单上传的时候,就可以使用它来构造我们的requestBody。
File file = new File(Environment.getExternalStorageDirectory(), "balabala.mp4");
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"username\""),
RequestBody.create(null, "张鸿洋"))
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"mFile\";
filename=\"wjd.mp4\""), fileBody)
.build();
Request request = new Request.Builder()
.url("http://192.168.1.103:8080/okHttpServer/fileUpload")
.post(requestBody)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback()
{
//...
});
上述代码向服务器传递了一个键值对username:张鸿洋和一个文件。我们通过MultipartBuilder的addPart方法可以添加键值对或者文件。
2.异步POST请求
OkHttp3异步POST请求和OkHttp2.x有一些差别就是没有FormEncodingBuilder这个类,替代它的是功能更加强大的FormBody:
3.异步上传文件
上传文件本身也是一个POST请求,上一篇没有讲,这里我们补上。首先定义上传文件类型:
public static final MediaType MEDIA_TYPE_MARKDOWN
= MediaType.parse("text/x-markdown; charset=utf-8");
将sdcard根目录的wangshu.txt文件上传到服务器上:
private void postAsynFile() {
mOkHttpClient=new OkHttpClient();
File file = new File("/sdcard/wangshu.txt");
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
.build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i("wangshu",response.body().string());
}
});
}
当然如果想要改为同步的上传文件只要调用 mOkHttpClient.newCall(request).execute()就可以了。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4.异步下载文件
下载文件同样在上一篇没有讲到,实现起来比较简单,在这里下载一张图片,我们得到Response后将流写进我们指定的图片文件中就可以了。
private void downAsynFile() {
mOkHttpClient = new OkHttpClient();
String url = "https://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/wangshu.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) {
Log.i("wangshu", "IOException");
e.printStackTrace();
}
Log.d("wangshu", "文件下载成功");
}
});
}
5.异步上传Multipart文件
这种场景很常用,我们有时会上传文件同时还需要传其他类型的字段,OkHttp3实现起来很简单,需要注意的是没有服务器接收我这个Multipart文件,所以这里只是举个例子,具体的应用还要结合实际工作中对应的服务器。
首先定义上传文件类型:
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
- 1
- 1
private void sendMultipart(){
mOkHttpClient = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "wangshu")
.addFormDataPart("image", "wangshu.jpg",
RequestBody.create(MEDIA_TYPE_PNG, new File("/sdcard/wangshu.jpg")))
.build();
Request request = new Request.Builder()
.header("Authorization", "Client-ID " + "...")
.url("https://api.imgur.com/3/image")
.post(requestBody)
.build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i("wangshu", response.body().string());
}
});
}
6.设置超时时间和缓存
和OkHttp2.x有区别的是不能通过OkHttpClient直接设置超时时间和缓存了,而是通过OkHttpClient.Builder来设置,通过builder配置好OkHttpClient后用builder.build()来返回OkHttpClient,所以我们通常不会调用new OkHttpClient()来得到OkHttpClient,而是通过builder.build():
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();