Android 一個改善的okHttp封裝庫
轉載請標明出處:
http://blog.csdn.net/lmj623565791/article/details/49734867;
本文出自:【張鴻洋的博客】
一、概述
之前寫了篇Android OkHttp全然解析 是時候來了解OkHttp了,事實上主要是作為okhttp的普及文章,當然裏面也簡單封裝了工具類,沒想到關註和使用的人還挺多的,因為這股熱情,該工具類中的方法也是劇增,各種重載方法,以致於使用起來極不方便。實在羞愧。
於是,在這個周末,抽點時間對該工具類,進行了又一次的拆解與編寫。順便完好下功能,盡可能的提升其使用起來的方便性和易擴展性。
標題的改善,也是指的是對於我之前的代碼進行改善。
假設你對okhttp不了解,能夠通過Android OkHttp全然解析 是時候來了解OkHttp了進行了解。
ok。那麽眼下,該封裝庫誌支持:
- 一般的get請求
- 一般的post請求
- 基於Http的文件上傳
- 文件下載
- 上傳下載的進度回調
- 載入圖片
- 支持請求回調。直接返回對象、對象集合
- 支持session的保持
- 支持自簽名站點https的訪問,提供方法設置下證書就可以
- 支持取消某個請求
源代碼地址:https://github.com/hongyangAndroid/okhttp-utils
引入:
Android Studio
使用前。對於Android Studio的用戶。能夠選擇加入:
compile project(‘:okhttputils‘)
或者
compile ‘com.zhy:okhttputils:2.0.0‘
Eclipse
自行copy源代碼。
二、基本使用方法
眼下基本的使用方法格式為:
OkHttpUtils
.get()
.url(url)
.addParams("username", "hyman")
.addParams("password", "123")
.build()
.execute(callback);
通過鏈式去依據自己的須要加入各種參數,最後調用execute(callback)進行運行,傳入callback則代表是異步。假設單純的execute()則代表同步的方法調用。
能夠看到,取消了之前一堆的get重載方法。參數也能夠進行靈活的選擇了。
以下簡單看一下,全部的使用方法:
(1)GET請求
String url = "http://www.csdn.net/";
OkHttpUtils
.get()
.url(url)
.addParams("username", "hyman")
.addParams("password", "123")
.build()
.execute(new StringCallback()
{
@Override
public void onError(Request request, Exception e)
{
}
@Override
public void onResponse(String response)
{
}
});
(2)POST請求
OkHttpUtils
.post()
.url(url)
.addParams("username", "hyman")
.addParams("password", "123")
.build()
.execute(callback);
(3)Post String
OkHttpUtils
.postString()
.url(url)
.content(new Gson().toJson(new User("zhy", "123")))
.build()
.execute(new MyStringCallback());
將string作為請求體傳入到服務端,比如json字符串。
(4)Post File
OkHttpUtils
.postFile()
.url(url)
.file(file)
.build()
.execute(new MyStringCallback());
將file作為請求體傳入到服務端.
(5)基於POST的文件上傳(相似web上的表單)
OkHttpUtils.post()//
.addFile("mFile", "messenger_01.png", file)//
.addFile("mFile", "test1.txt", file2)//
.url(url)
.params(params)//
.headers(headers)//
.build()//
.execute(new MyStringCallback());
(6)下載文件
OkHttpUtils//
.get()//
.url(url)//
.build()//
.execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), "gson-2.2.1.jar")//
{
@Override
public void inProgress(float progress)
{
mProgressBar.setProgress((int) (100 * progress));
}
@Override
public void onError(Request request, Exception e)
{
Log.e(TAG, "onError :" + e.getMessage());
}
@Override
public void onResponse(File file)
{
Log.e(TAG, "onResponse :" + file.getAbsolutePath());
}
});
(7)顯示圖片
OkHttpUtils
.get()//
.url(url)//
.build()//
.execute(new BitmapCallback()
{
@Override
public void onError(Request request, Exception e)
{
mTv.setText("onError:" + e.getMessage());
}
@Override
public void onResponse(Bitmap bitmap)
{
mImageView.setImageBitmap(bitmap);
}
});
哈,眼下來看。清晰多了。
三、對於上傳下載的回調
new Callback<?>()
{
//...
@Override
public void inProgress(float progress)
{
//use progress: 0 ~ 1
}
}
對於傳入的callback有個inProgress方法,須要拿到進度直接復寫該方法就可以。
四、對於自己主動解析為實體類
眼下去除了Gson的依賴,提供了自己定義Callback的方式,讓用戶自己去解析返回的數據,眼下提供了StringCallback
。FileCallback
,BitmapCallback
分別用於返回string。文件下載,載入圖片。
當然假設你希望解析為對象,你能夠:
public abstract class UserCallback extends Callback<User>
{
//非UI線程,支持不論什麽耗時操作
@Override
public User parseNetworkResponse(Response response) throws IOException
{
String string = response.body().string();
User user = new Gson().fromJson(string, User.class);
return user;
}
}
自己使用自己喜歡的Json解析庫完畢就可以。
解析成List<User>
,則例如以下:
public abstract class ListUserCallback extends Callback<List<User>>
{
@Override
public List<User> parseNetworkResponse(Response response) throws IOException
{
String string = response.body().string();
List<User> user = new Gson().fromJson(string, List.class);
return user;
}
}
五、對於https單向認證
很easy,拿到xxx.cert的證書。
然後調用
OkHttpUtils.getInstance()
.setCertificates(inputstream);
建議使用方式,比如我的證書放在assets文件夾:
/**
* Created by zhy on 15/8/25.
*/
public class MyApplication extends Application
{
@Override
public void onCreate()
{
super.onCreate();
try
{
OkHttpUtils
.getInstance()
.setCertificates(getAssets().open("aaa.cer"),
getAssets().open("server.cer"));
} catch (IOException e)
{
e.printStackTrace();
}
}
}
就可以。別忘了註冊Application。
註意:假設https站點為權威機構頒發的證書,不須要以上設置。自簽名的證書才須要。
六、配置
(1)全局配置
能夠在Application中。通過:
OkHttpClient client =
OkHttpUtils.getInstance().getOkHttpClient();
然後調用client的各種set方法。
比如:
client.setConnectTimeout(100000, TimeUnit.MILLISECONDS);
(2)為單個請求設置超時
比方涉及到文件的須要設置讀寫等待時間多一點。
OkHttpUtils
.get()//
.url(url)//
.tag(this)//
.build()//
.connTimeOut(20000)
.readTimeOut(20000)
.writeTimeOut(20000)
.execute()
調用build()之後。能夠隨即設置各種timeOut.
(3)取消單個請求
RequestCall call = OkHttpUtils.get().url(url).build();
call.cancel();
(4)依據tag取消請求
眼下對於支持的方法都加入了最後一個參數Object tag
,取消則通過OkHttpUtils.cancelTag(tag)
運行。
比如:在Activity中,當Activity銷毀取消請求:
OkHttpUtils
.get()//
.url(url)//
.tag(this)//
.build()//
@Override
protected void onDestroy()
{
super.onDestroy();
//能夠取消同一個tag的
OkHttpUtils.cancelTag(this);//取消以Activity.this作為tag的請求
}
比方,當前Activity頁面全部的請求以Activity對象作為tag。能夠在onDestory裏面統一取消。
七、淺談封裝
事實上整個封裝的過程比較簡單,這裏簡單描寫敘述下,對於okhttp一個請求的流程大致是這種:
//創建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();
}
});
當中基本的差異,事實上就是request的構建過程。
我對Request抽象了一個類:OkHttpRequest
public abstract class OkHttpRequest
{
protected RequestBody requestBody;
protected Request request;
protected String url;
protected String tag;
protected Map<String, String> params;
protected Map<String, String> headers;
protected OkHttpRequest(String url, String tag,
Map<String, String> params, Map<String, String> headers)
{
this.url = url;
this.tag = tag;
this.params = params;
this.headers = headers;
}
protected abstract Request buildRequest();
protected abstract RequestBody buildRequestBody();
protected void prepareInvoked(ResultCallback callback)
{
requestBody = buildRequestBody();
requestBody = wrapRequestBody(requestBody, callback);
request = buildRequest();
}
protected RequestBody wrapRequestBody(RequestBody requestBody, final ResultCallback callback)
{
return requestBody;
}
public void invokeAsyn(ResultCallback callback)
{
prepareInvoked(callback);
mOkHttpClientManager.execute(request, callback);
}
// other common methods
}
一個request的構建呢,我分三個步驟:buildRequestBody
, wrapRequestBody
,buildRequest
這種次序,當以上三個方法沒有問題時,我們就拿到了request。然後運行就可以。
可是對於不同的請求。requestBody以及request的構建過程是不同的。所以大家能夠看到buildRequestBody
,buildRequest
為抽象的方法,也就是不同的請求類。比方OkHttpGetRequest
、OkHttpPostRequest
等須要自己去構建自己的request。
對於wrapRequestBody
方法呢,能夠看到它默認基本屬於空實現,主要是因為並不是全部的請求類都須要復寫它,僅僅有上傳的時候呢,須要回調進度。須要對requestBody進行包裝。所以這種方法相似於一個鉤子。
事實上這個過程有點相似模板方法模式,有興趣能夠看看一個短篇介紹設計模式 模版方法模式 展現程序猿的一天 .
對於更加具體的使用方法,能夠查看github上面的readme。以及demo,眼下demo包括:
對於上傳文件的兩個button,須要自己搭建服務器。其它的button能夠直接測試。
最後,因為本人水平有限。以及時間比較倉促~~發現問題,歡迎提issue,我會抽時間解決。 have a nice day ~
源代碼點擊下載
歡迎關註我的微博:
http://weibo.com/u/3165018720
群號:514447580,歡迎入群
微信公眾號:hongyangAndroid
(歡迎關註,第一時間推送博文信息)
Android 一個改善的okHttp封裝庫