Android 一个改善的okHttp封装库 2015-12-15 14:36
http://blog.csdn.net/lmj623565791/article/details/49734867/#reply
Android OkHttp完全解析 是时候来了解OkHttp了 本文出自:【张鸿洋的博客】 2015-08-24 15:36
http://blog.csdn.net/lmj623565791/article/details/47911083
注意:okhttp内部依赖okio,别忘了同时导入okio:
最近在群里听到各种讨论okhttp的话题,可见okhttp的口碑相当好了。再加上Google貌似在6.0版本里面删除了HttpClient相关API,对于这个行为不做评价。为了更好的在应对网络访问,学习下okhttp还是蛮必要的,本篇博客首先介绍okhttp的简单使用,主要包含:
最后会对上述几个功能进行封装,完整的封装类的地址见:https://github.com/hongyangAndroid/okhttp-utils
对了网络加载库,那么最常见的肯定就是http get请求了,比如获取一个网页的内容。
//创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
//创建一个Request
final Request request = new Request.Builder()
.url("https://github.com/hongyangAndroid")
.build();
//new call
Call call = mOkHttpClient.newCall(request);
//请求加入调度
call.enqueue(new Callback()
{
@Override
public void onFailure(Request request, IOException e)
{
}
@Override
public void onResponse(final Response response) throws IOException
{
//String htmlStr = response.body().string();
}
});
以上就是发送一个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等,例如:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onResponse</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Response response) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> IOException { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String res = response.body().string(); runOnUiThread(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Runnable() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">run</span>() { mTv.setText(res); } }); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>
execute()
方法,你也可以直接调用call.execute()
通过返回一个Response
。
http://blog.csdn.net/chenzujie/article/details/46994073 后面还有几篇OKHttp源码解析的其他文章
简单的对于OKHttp的使用就介绍到这里,下次将重点从源码角度介绍整个OKHttp是如何运转的。
POST情况下我们一般需要传入参数,甚至一些header,传入参数或者header
比如传入header
Request request = new Request.Builder()
.url("https://api.github.com/repos/square/okhttp/issues")
.header("User-Agent", "OkHttp Headers.java")
.addHeader("Accept", "application/json; q=0.5")
.addHeader("Accept", "application/vnd.github.v3+json")
.build();
传入POST参数
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">RequestBody formBody = new FormEncodingBuilder() <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.add</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"platform"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"android"</span>) <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.add</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"name"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"bug"</span>) <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.add</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"subject"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"XXXXXXXXXXXXXXX"</span>) <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.build</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> Request request = new Request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Builder</span>() <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.url</span>(url) <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.post</span>(body) <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.build</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>
可以看出来,传入header或者post参数都是传到Request里面,因此最后的调用方式也和GET方式一样
<code class="hljs vbscript has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Response</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">response</span> = client.newCall(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">request</span>).<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">execute</span>(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">response</span>.isSuccessful()) { return <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">response</span>.body().<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span>(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { throw <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IOException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Unexpected code "</span> + <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">response</span>); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
这个代码是同步网络请求,异步就改成enqueue就行了。
在网络请求中,缓存技术是一项应用比较广泛的技术,需要对请求过的网络资源进行缓存,而okhttp也支持这一技术,也使用十分方便,前文涨经常出现的OkHttpclient这个时候就要派送用场了。
File sdcache = getExternalCacheDir() ;int cacheSize =10 * 1024 * 1024; // 10 MiB
client.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));