前言
OkHttp是一个高效的HTTP库
Ø 支持 SPDY ,共享同一个Socket来处理同一个服务器的所有请求;
Ø 如果SPDY不可用,则通过连接池来减少请求延时;
Ø 无缝的支持GZIP来减少数据流量;
Ø 缓存响应数据来减少重复的网络请求。
l 官网地址
http://square.github.io/okhttp/
l Githut地址
https://github.com/square/okhttp
l 引入依赖
compile'com.squareup.okhttp3:okhttp:3.2.0'
l 原文地址
http://blog.csdn.net/tangxl2008008/article/details/51730187
基本使用
以最新的okhttp3为例。
1. Http-GET
1) OkHttpClient:新建一个OkHttpClient实例,用于处理请求。
2) Request:构建请求参数,如url,请求方式,请求参数,header等。
3) Call:生成一个具体请求实例,相当于将请求封装成了任务;两种方式:
①、call.execute(),非异步方式,会阻塞线程,等待返回结果。
②、call.enqueue(Callback),异步方式。
4) Response:结果响应。
final String url = "http://www.weather.com.cn/data/sk/101010100.html"; // OkHttpClient okHttpClient = new OkHttpClient(); final okhttp3.Request request = new okhttp3.Request.Builder() .url(url) .build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG, "onFailure() e=" + e); } @Override public void onResponse(Call call, final Response response) throws IOException { Log.i(TAG, " onResponse() reuslt=" + response.body().string()); } }); |
说明:
① onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()。
② Callback的onFailure()及onResponse()运行在非主线程,不能在该方法中直接进行UI操作。
2. Http-POST
POST请求跟Get基本相同,需要增加RequestBody来存储请求的参数信息;在Request.Builder中增加post(RequestBody)调用。
RequestBody requestBody = new FormBody.Builder() .add("key", "value") .build(); final okhttp3.Request request = new okhttp3.Request.Builder() .url(url) .post(requestBody) .build(); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG, "testHttpPost ... onFailure() e=" + e); } @Override public void onResponse(Call call, Response response) throws IOException { Log.i(TAG, "testHttpPost ... onResponse() response=" + response.body().string()); } }); |
有时调试需要查看参数信息,可以通过该方式,获取得到参数信息:
public String getParameters(RequestBody requestBody) { try { final Buffer buffer = new Buffer(); requestBody.writeTo(buffer); // BufferedInputStream bufferedInputStream = new BufferedInputStream(buffer.inputStream()); final StringBuffer resultBuffer = new StringBuffer(); byte[] inputBytes = new byte[1024]; while (true) { int count = bufferedInputStream.read(inputBytes); if (count <= 0) { break; } resultBuffer.append(new String(Arrays.copyOf(inputBytes, count), Util.UTF_8)); } final String parameter = URLDecoder.decode(resultBuffer.toString(), Util.UTF_8.name()); bufferedInputStream.close(); return parameter; } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null; } |
3. RxJava中使用call.execute()
call.execute()是阻塞式返回数据方式,可以和RxJava配合使用;关于RxJava使用参看“RxJava使用”部分。
final String url = "http://www.weather.com.cn/data/sk/101010100.html"; // final okhttp3.Request request = new okhttp3.Request.Builder() .url(url) .build(); rx.Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { try { //处理请求在IO线程中进行 final Response response = mOkHttpClient.newCall(request).execute(); subscriber.onNext(response.body().string()); } catch (IOException e) { e.printStackTrace(); subscriber.onError(e); } } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { showInfo(e.toString()); } @Override public void onNext(String s) { //处理返回结果,在UI线程中,可以直接显示结果 showInfo(s); } }) ; |
① 可以通过使用RxJava的map及flatMap过程,直接将json结果转换为具体的数据bean信息(下面以获取天气信息为例,Weatherinfo为自定义的天气信息bean类);具体map及flatMap使用参考“RxJava使用(四)变换”部分。
② 该部分需要依赖GSON包。
final String url = "http://www.weather.com.cn/data/sk/101010100.html"; // rx.Observable.just(url) .map(new Func1<String, WeatherinfoResult>() { @Override public WeatherinfoResult call(String s) { final okhttp3.Request request = new okhttp3.Request.Builder() .url(s) .build(); try { final Response response = mOkHttpClient.newCall(request).execute(); //将获取的天气json数据,转换为WeatherinfoResult return JsonUtil.parseData(response.body().string(), WeatherinfoResult.class); } catch (IOException e) { e.printStackTrace(); } return null; } }) .flatMap(new Func1<WeatherinfoResult, Observable<Weatherinfo>>() { @Override public Observable<Weatherinfo> call(WeatherinfoResult weatherinfoResult) { return Observable.just(weatherinfoResult.getWeatherinfo()); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<Weatherinfo>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { showInfo("error:" + e.toString()); } @Override public void onNext(Weatherinfo s) { showInfo(s.toString()); } }) ; |