轉載出處:
http://blog.csdn.net/lmj623565791/article/details/49734867;
本文出自:【張鴻洋的博客】html
以前寫了篇Android OkHttp徹底解析 是時候來了解OkHttp了,其實主要是做爲okhttp的普及文章,固然裏面也簡單封裝了工具類,沒想到關注和使用的人還挺多的,因爲這股熱情,該工具類中的方法也是劇增,各類重載方法,以至於使用起來極不方便,實在慚愧。android
因而,在這個週末,抽點時間對該工具類,進行了從新的拆解與編寫,順便完善下功能,儘量的提高其使用起來的方便性和易擴展性。git
標題的改善,也是指的是對於我以前的代碼進行改善。程序員
若是你對okhttp不瞭解,能夠經過Android OkHttp徹底解析 是時候來了解OkHttp了進行了解。github
ok,那麼目前,該封裝庫志支持:web
源碼地址:https://github.com/hongyangAndroid/okhttp-utilsjson
引入:設計模式
Android Studio服務器
使用前,對於Android Studio的用戶,能夠選擇添加:session
compile project(':okhttputils')
或者
compile 'com.zhy:okhttputils:2.0.0'
目前基本的用法格式爲:
OkHttpUtils .get() .url(url) .addParams("username", "hyman") .addParams("password", "123") .build() .execute(callback);
經過鏈式去根據本身的須要添加各類參數,最後調用execute(callback)進行執行,傳入callback則表明是異步。若是單純的execute()則表明同步的方法調用。
能夠看到,取消了以前一堆的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) { } });
OkHttpUtils .post() .url(url) .addParams("username", "hyman") .addParams("password", "123") .build() .execute(callback);
OkHttpUtils .postString() .url(url) .content(new Gson().toJson(new User("zhy", "123"))) .build() .execute(new MyStringCallback());
將string做爲請求體傳入到服務端,例如json字符串。
OkHttpUtils .postFile() .url(url) .file(file) .build() .execute(new MyStringCallback());
將file做爲請求體傳入到服務端.
OkHttpUtils.post()// .addFile("mFile", "messenger_01.png", file)// .addFile("mFile", "test1.txt", file2)// .url(url) .params(params)// .headers(headers)// .build()// .execute(new MyStringCallback());
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()); } });
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; } }
很是簡單,拿到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網站爲權威機構頒發的證書,不須要以上設置。自簽名的證書才須要。
能夠在Application中,經過:
OkHttpClient client =
OkHttpUtils.getInstance().getOkHttpClient();
而後調用client的各類set方法。
例如:
client.setConnectTimeout(100000, TimeUnit.MILLISECONDS);
好比涉及到文件的須要設置讀寫等待時間多一點。
OkHttpUtils .get()// .url(url)// .tag(this)// .build()// .connTimeOut(20000) .readTimeOut(20000) .writeTimeOut(20000) .execute()
調用build()以後,能夠隨即設置各類timeOut.
RequestCall call = OkHttpUtils.get().url(url).build();
call.cancel()
目前對於支持的方法都添加了最後一個參數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包含:
對於上傳文件的兩個按鈕,須要本身搭建服務器,其餘的按鈕能夠直接測試。
最後,因爲本人水平有限,以及時間比較倉促~~發現問題,歡迎提issue,我會抽時間解決。 have a nice day ~