Android 開發框架之okhttp 網絡框架的學習


一.概述

主要包含如下功能:

    一般的get請求
    一般的post請求
    基於Http的文件上傳
    文件下載
    加載圖片
    支持請求回調,直接返回對象、對象集合
    支持session的保持

可以下載最新的jar okhttp he latest JAR ,添加依賴就可以用了。注意:okhttp內部依賴okio,別忘了同時導入okio,最新的jar地址:okio the latest JAR


或者gradle 添加

<span style="font-size:14px;"><code class="language-xml hljs  has-numbering">compile 'com.squareup.okhttp:okhttp:2.4.0'
<code>compile 'com.squareup.okio:okio:1.5.0'

</code></code></span>

1.Okhttp發送一個get請求


//
使用Okhttp發送一個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();
Log.e(TAG,"html = "+htmlStr);
}
});

以上就是發送一個get請求的步驟,首先構造一個Request對象,參數最起碼有個url,當然你可以通過Request.Builder設置更多的參數比如:header、method等。

    然后通過request的對象去構造得到一個Call對象,類似於將你的請求封裝成了任務,既然是任務,就會有execute()和cancel()等方法。

    最后,我們希望以異步的方式去執行請求,所以我們調用的是call.enqueue,將call加入調度隊列,然后等待任務執行完成,我們在Callback中即可得到結果。

注意:

onResponse回調的參數是response,一般情況下,比如我們希望獲得返回的字符串,可以通過response.body().string()獲取;如果希望獲得返回的二進制字節數組,則調用response.body().bytes();如果你想拿到返回的inputStream,則調用response.body().byteStream(),看到這,能拿到返回的inputStream,看到這個能意識到一點,這里支持大文件下載,有inputStream我們就可以通過IO的方式寫文件。不過也說明一個問題,這個onResponse執行的線程並不是UI線程。的確是的,如果你希望操作控件,還是需要使用handler等

2.Http Post 攜帶參數

//Okhttppost 請求
String url = "www.baidu.com";
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("username","張鴻洋");

Request request = new Request.Builder()
.url(url)
.post(builder.build())
.build();
mOkHttpClient.newCall(request).enqueue(new Callback(){
@Override
public void onFailure(Request request, IOException e) {

}

@Override
public void onResponse(Response response) throws IOException {

}
});
post的時候,參數是包含在請求體中的;所以我們通過FormEncodingBuilder。添加多個String鍵值對,然后去構造RequestBody,最后完成我們Request的構造。

3.基於Http的文件上傳

使用 MultipartBuilder。當我們需要做類似於表單上傳的時候,就可以使用它來構造我們的requestBody

參考如下代碼

//post提交文件
File file = new File("readme123.md");
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("https://github.com/prsioner/MyfxUtils3Demo")
.post(requestBody)
.build();

Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
Log.e(TAG,"request failed ="+request);
}

@Override
public void onResponse(Response response) throws IOException {
Log.e(TAG,"resposebody ="+response.body().string());
}
});
對於圖片下載,文件下載;這兩個一個是通過回調的Response拿到byte[]然后decode成圖片;文件下載,就是拿到inputStream做寫文件操作,我們這里就不贅述了,參考泡在網上的日子。

4.封裝網絡請求代碼


列舉鴻洋對okhttp的封裝,下面是通過url 返回一個string 字符串。

public void getHtml(View view)
{
String url = "http://sec.mobile.tiancity.com/server/mobilesecurity/version.xml";
url="http://www.391k.com/api/xapi.ashx/info.json?key=bd_hyrzjjfb4modhj&size=10&page=1";
OkHttpUtils
.get()
.url(url)
// .addHeader("Accept-Encoding","")
.build()
.execute(new MyStringCallback());

}
通過OkHttpUtils.get()方法獲取到GetBuilder() 對象,調用url設置url到builder對象,調用build()方法返回一個帶
參數的requset.builde(),最后返回來的是一個requset對象

public RequestCall build()
{
if (params != null)
{
url = appendParams(url, params);
}

return new GetRequest(url, tag, params, headers).build();
}
requset類如下

public class RequestCall
{
private OkHttpRequest okHttpRequest;
private Request request;
private Call call;

private long readTimeOut;
private long writeTimeOut;
private long connTimeOut;

private OkHttpClient clone;

public RequestCall(OkHttpRequest request)
{
this.okHttpRequest = request;
}
這個requset對象跟上文的

//創建一個Request
final Request request = new Request.Builder()
.url("https://github.com/hongyangAndroid")
.build();
是一個對象,只是后者進行了封裝,簡化了代碼。

之后調用Requset.execure()方法把請求加入調度

public void execute(final RequestCall requestCall, Callback callback)
{
if (callback == null)
callback = Callback.CALLBACK_DEFAULT;
final Callback finalCallback = callback;

requestCall.getCall().enqueue(new okhttp3.Callback()
{
@Override
public void onFailure(Call call, final IOException e)
{
sendFailResultCallback(call, e, finalCallback);
}
@Override
public void onResponse(final Call call, final Response response)
{
// if (response.code() >= 400 && response.code() <= 599)
// {
// try
// {
// sendFailResultCallback(call, new RuntimeException(response.body().string()), finalCallback);
// } catch (IOException e)
// {
// e.printStackTrace();
// }
// return;
// }

try
{
Object o = finalCallback.parseNetworkResponse(response);
sendSuccessResultCallback(o, finalCallback);
} catch (Exception e)
{
sendFailResultCallback(call, e, finalCallback);

}

}
});
}
大致過程就是這樣,鴻洋正是大神,非常清晰的寫好了封裝后的可供調用的接口,膜拜下!!

實例代碼只是調用了

getHtml(mTv);
getImage(mImageView);
這兩個封裝的方法,是不是很方便呢,其他網絡請求類似。

直接看源碼吧,點擊下載!!

參考:泡在網上的日子:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html

鴻洋的博客:http://blog.csdn.net/lmj623565791/article/details/47911083


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com