OkHttpUtils-2.0.0 升級後改名 OkGo,全新完美支援 RxJava,比 Retrofit 更簡單易用。
該庫是封裝了 okhttp 的標準 RESTful 風格的網路框架,可以與 RxJava 完美結合,比 Retrofit 更簡單易用。支援大檔案上傳下載,上傳進度回撥,下載進度回撥,表單上傳(多檔案和多引數一起上傳),鏈式呼叫,可以自定義返回物件,支援 Https 和自簽名證書,支援超時自動重連,支援 cookie 與 session 的自動管理,支援四種快取模式快取網路資料,支援 301、302 重定向,擴充套件了統一的上傳管理和下載管理功能
該專案參考了以下專案:
在此特別感謝上述作者,喜歡原作的可以去使用原專案。同時歡迎大家下載體驗本專案,如果使用過程中遇到什麼問題,歡迎反饋。
聯絡方式
- 郵箱地址:
- QQ 群: 489873144 (建議使用 QQ 群,郵箱使用較少,可能看的不及時)
- 本群旨在為使用我的 github 專案的人提供方便,如果遇到問題歡迎在群裡提問。個人能力也有限,希望一起學習一起進步。
演示
文件目錄(點選快速導航)
1.用法
請抓包看網路資料,log 有些資料不列印,不會抓包請百度,學一次受用終生,重要的事情說三遍
請抓包看網路資料,log 有些資料不列印,不會抓包請百度,學一次受用終生,重要的事情說三遍
請抓包看網路資料,log 有些資料不列印,不會抓包請百度,學一次受用終生,重要的事情說三遍
- 為了方便大家使用,更加通俗的理解 http 的網路協議,建議做網路請求的時候,對每個請求抓包後檢視請求資訊和響應資訊。
- 如果是 Windows 作業系統,可以使用
Fiddler
對手機的請求進行抓包檢視。- 如果是 Mac OS 作業系統,可以使用
Charles
對手機的請求進行抓包檢視。- 具體的下載地址和抓包配置方法,我這就不提供了,請自行百度或谷歌。
對於 Eclipse 不能執行專案的,提供了 apk 供直接執行
本專案 Demo 的網路請求是我自己的伺服器,有時候可能不穩定,網速比較慢時請耐心等待。。
以下是最新版本的版本號,如果你想使用以前的版本,請點選這裡,歷史版本。
- 對於 Android Studio 的使用者,可以選擇新增:
compile 'com.lzy.net:okgo:2.1.4' //可以單獨使用,不需要依賴下方的擴充套件包 compile 'com.lzy.net:okrx:0.1.2' //RxJava 擴充套件支援,根據需要新增 compile 'com.lzy.net:okserver:1.1.3' //下載管理和上傳管理擴充套件,根據需要新增 或者 compile 'com.lzy.net:okgo:+' //版本號使用 + 可以自動引用最新版 compile 'com.lzy.net:okrx:+' //版本號使用 + 可以自動引用最新版 compile 'com.lzy.net:okserver:+' //版本號使用 + 可以自動引用最新版
- 對於 Eclipse 的使用者,可以選擇新增
/jar
目錄下的: ```java okhttp-3.4.1.jar //okhttp 官方包 (必須導) okio-1.9.0.jar //okio 官方包(必須導) okgo-2.1.4.jar //okgo 基本功能包(必須導)
okrx-0.1.2.jar //okrx 擴充套件支援包,想用 rxjava 呼叫的必須要導(同時還需要 rxjava 的 jar,自行下載,不提供) okserver-1.1.3.jar //okserver 擴充套件支援包,使用下載管理必須要
* 如果是以 jar 包的形式引入`okserver`,需要在清單檔案中額外註冊一個服務
```java
<service android:name="com.lzy.okserver.download.DownloadService"/>
- 如果只是用了
okgo
的 jar,沒有使用okserver
的 jar,那麼不需要註冊上面的服務
其中的圖片選擇是我的另一個開源專案,完全仿微信的圖片選擇庫,自帶 矩形圖片裁剪 和 圓形圖片裁剪 功能,有需要的可以去下載使用,附上地址:https://github.com/jeasonlzy/ImagePicker
其中的九宮格控制元件也是我的開源專案,類似 QQ 空間,微信朋友圈,微博主頁等,展示圖片的九宮格控制元件,自動根據圖片的數量確定圖片大小和控制元件大小,使用 Adapter 模式設定圖片,對外提供介面回撥,使用介面載入圖片,支援任意的圖片載入框架,如 Glide,ImageLoader,Fresco,xUtils3,Picasso 等,支援點選圖片全屏預覽大圖。附上地址:https://github.com/jeasonlzy/NineGridView
2.使用注意事項
okgo
使用的okhttp
的版本是最新的 3.4.1 版本,和以前的 2.x 的版本可能會存在衝突。okrx
是基於RxJava
和RxAndroid
的擴充套件,如果不需要可以不必引入okserver
是對okgo
的擴充套件,統一了下載管理和上傳管理,對專案有需要做統一下載的可以考慮使用該擴充套件,不需要的可以直接使用okgo
即可。- 對於快取模式使用,需要與返回物件相關的所有
javaBean
必須實現Serializable
介面,否者會報NotSerializableException
。 - 使用快取時,如果不指定
cacheKey
,預設是用 url 帶引數的全路徑名為cacheKey
。 - 使用該網路框架時,必須要在 Application 中做初始化
OkGo.init(this);
。
3.OkGo 目前支援
- 一般的 get,post,put,delete,head,options 請求
- 基於 Post 的大文字資料上傳
- 多檔案和多引數統一的表單上傳
- 支援一個 key 上傳一個檔案,也可以一個 Key 上傳多個檔案
- 大檔案下載和下載進度回撥
- 大檔案上傳和上傳進度回撥
- 支援 cookie 的記憶體儲存和持久化儲存,支援傳遞自定義 cookie
- 支援 304 快取協議,擴充套件四種本地快取模式,並且支援快取時間控制
- 支援 301、302 重定向
- 支援自定義超時自動重連次數
- 支援鏈式呼叫
- 支援可信證書和自簽名證書的 https 的訪問,支援雙向認證
- 支援根據 Tag 取消請求
- 支援自定義泛型 Callback,自動根據泛型返回物件
4.OkRx 擴充套件功能
- 完美結合 RxJava
- 比 Retrofit 更簡單方便
- 網路請求和 RxJava 呼叫,一條鏈點到底
- 支援 Json 資料的自動解析轉換
- OkGo 包含的所有請求功能,OkRx 全部支援
5.OkServer 擴充套件功能
該功能並沒有在文件中寫出,詳細使用方法請自行看 demo 中的程式碼,有詳細的註釋,不在文件中贅述。
5.1 統一的檔案下載管理(DownloadManager):
- 結合 OkGo 的 request 進行網路請求,支援與 OkGo 保持相同的全域性公共引數,同時支援請求傳遞引數
- 支援斷點下載,支援突然斷網,強殺程序後,斷點依然有效
- 支援 下載 暫停 等待 停止 出錯 完成 六種下載狀態
- 所有下載任務按照 taskKey 區分,切記不同的任務必須使用不一樣的 key,否者斷點會發生覆蓋
- 相同的下載 url 地址如果使用不一樣的 taskKey,也會認為是兩個下載任務
- 默認同時下載數量為 3 個,預設下載路徑
/storage/emulated/0/download
,下載路徑和下載數量都可以在程式碼中配置 - 下載檔名可以自己定義,也可以不傳,框架自動解析響應頭或者 url 地址獲得檔名,如果都沒獲取到,使用 default 作為檔名
- 下載管理使用了服務提高執行緒優先順序,避免後臺下載時被系統回收
5.2 統一的檔案上傳管理(UploadManager)
- 結合 OkGo 的 request 進行網路請求,支援與 OkGo 保持相同的全域性公共引數,同時支援請求傳遞引數
- 上傳只能使用
Post
,Put
,Delete
,Options
這四種請求,不支援Get
,Head
- 該上傳管理為簡單管理,不支援斷點續傳或分片上傳,只是簡單的將所有上傳任務使用執行緒池進行了統一管理
- 默認同時上傳數量為 1 個,該數列可以在程式碼中配置修改
���、全域性配置
一般在 Aplication,或者基類中,只需要呼叫一次即可,可以配置除錯開關,全域性的超時時間,公共的請求頭和請求引數等資訊
不要忘記了在清單檔案中註冊 Aplication
@Override
public void onCreate() {
super.onCreate();
//---------這裡給出的是示例程式碼,告訴你可以這麼傳,實際使用的時候,根據需要傳,不需要就不傳-------------//
HttpHeaders headers = new HttpHeaders();
headers.put("commonHeaderKey1", "commonHeaderValue1"); //header 不支援中文
headers.put("commonHeaderKey2", "commonHeaderValue2");
HttpParams params = new HttpParams();
params.put("commonParamsKey1", "commonParamsValue1"); //param 支援中文,直接傳,不要自己編碼
params.put("commonParamsKey2", "這裡支援中文引數");
//-----------------------------------------------------------------------------------//
//必須呼叫初始化
OkGo.init(this);
//以下設定的所有引數是全域性引數,同樣的引數可以在請求的時候再設定一遍,那麼對於該請求來講,請求中的引數會覆蓋全域性引數
//好處是全域性引數統一,特定請求可以特別定製引數
try {
//以下都不是必須的,根據需要自行選擇,一般來說只需要 debug,快取相關,cookie 相關的 就可以了
OkGo.getInstance()
// 開啟該除錯開關,列印級別 INFO,並不是異常,是為了顯眼,不需要就不要加入該行
// 最後的 true 表示是否列印 okgo 的內部異常,一般開啟方便除錯錯誤
.debug("OkGo", Level.INFO, true)
//如果使用預設的 60 秒,以下三行也不需要傳
.setConnectTimeout(OkGo.DEFAULT_MILLISECONDS) //全域性的連線超時時間
.setReadTimeOut(OkGo.DEFAULT_MILLISECONDS) //全域性的讀取超時時間
.setWriteTimeOut(OkGo.DEFAULT_MILLISECONDS) //全域性的寫入超時時間
//可以全域性統一設定快取模式,預設是不使用快取,可以不傳,具體其他模式看 github 介紹 https://github.com/jeasonlzy/
.setCacheMode(CacheMode.NO_CACHE)
//可以全域性統一設定快取時間,預設永不過期,具體使用方法看 github 介紹
.setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)
//可以全域性統一設定超時重連次數,預設為三次,那麼最差的情況會請求 4 次(一次原始請求,三次重連請求),不需要可以設定為 0
.setRetryCount(3)
//如果不想讓框架管理 cookie(或者叫 session 的保持),以下不需要
// .setCookieStore(new MemoryCookieStore()) //cookie 使用記憶體快取(app 退出後,cookie 消失)
.setCookieStore(new PersistentCookieStore()) //cookie 持久化儲存,如果 cookie 不過期,則一直有效
//可以設定 https 的證書,以下幾種方案根據需要自己設定
.setCertificates() //方法一:信任所有證書,不安全有風險
// .setCertificates(new SafeTrustManager()) //方法二:自定義信任規則,校驗服務端證書
// .setCertificates(getAssets().open("srca.cer")) //方法三:使用預埋證書,校驗服務端證書(自簽名證書)
// //方法四:使用 bks 證書和密碼管理客戶端證書(雙向認證),使用預埋證書,校驗服務端證書(自簽名證書)
// .setCertificates(getAssets().open("xxx.bks"), "123456", getAssets().open("yyy.cer"))//
//配置 https 的域名匹配規則,詳細看 demo 的初始化介紹,不需要就不要加入,使用不當會導致 https 握手失敗
// .setHostnameVerifier(new SafeHostnameVerifier())
//可以新增全域性攔截器,不需要就不要加入,錯誤寫法直接導致任何回撥不執行
// .addInterceptor(new Interceptor() {
// @Override
// public Response intercept(Chain chain) throws IOException {
// return chain.proceed(chain.request());
// }
// })
//這兩行同上,不需要就不要加入
.addCommonHeaders(headers) //設定全域性公共頭
.addCommonParams(params); //設定全域性公共引數
} catch (Exception e) {
e.printStackTrace();
}
}
二、普通請求
0.寫在開始的話,callback
回撥預設只需要複寫onSuccess
,並不代表所有的回撥都只走這一個,實際開發中,錯誤回撥並沒有成功回撥使用頻繁,所以callback
的失敗回撥onError
並沒有宣告為抽象的,如果有需要,請自行復寫,不要再問我為什麼回撥沒有執行啊,既然onSuccess
沒有執行,那麼一定是出錯了回調了onError
callback 一共有以下 10 個回撥,除onSuccess
必須實現以外,其餘均可以按需實現,每個方法引數詳細說明,請看下面第 6 點:
- convertSuccess():解析網路返回的資料回撥
- parseError():解析網路失敗的資料回撥
- onBefore():網路請求真正執行前回調
- onSuccess():網路請求成功的回撥
- onCacheSuccess():快取讀取成功的回撥
- onError():網路請求失敗的回撥
- onCacheError():網路快取讀取失敗的回撥
- onAfter():網路請求結束的回撥,無論成功失敗一定會執行
- upProgress():上傳進度的回撥
- downloadProgress():下載進度的回撥
Callback 回撥具有如下順序,雖然順序寫的很複雜,但是理解後,是很簡單,並且合情合理的
1).無快取模式 CacheMode.NO_CACHE
網路請求成功 onBefore -> convertSuccess -> onSuccess -> onAfter
網路請求失敗 onBefore -> parseError -> onError -> onAfter
2).預設快取模式,遵循 304 頭 CacheMode.DEFAULT
網路請求成功,服務端返回非 304 onBefore -> convertSuccess -> onSuccess -> onAfter
網路請求成功服務端返回 304 onBefore -> onCacheSuccess -> onAfter
網路請求失敗 onBefore -> parseError -> onError -> onAfter
3).請求網路失敗後讀取快取 CacheMode.REQUEST_FAILED_READ_CACHE
網路請求成功,不讀取快取 onBefore -> convertSuccess -> onSuccess -> onAfter
網路請求失敗,讀取快取成功 onBefore -> parseError -> onError -> onCacheSuccess -> onAfter
網路請求失敗,讀取快取失敗 onBefore -> parseError -> onError -> onCacheError -> onAfter
4).如果快取不存在才請求網路,否則使用快取 CacheMode.IF_NONE_CACHE_REQUEST
已經有快取,不請求網路 onBefore -> onCacheSuccess -> onAfter
沒有快取請求網路成功 onBefore -> onCacheError -> convertSuccess -> onSuccess -> onAfter
沒有快取請求網路失敗 onBefore -> onCacheError -> parseError -> onError -> onAfter
5).先使用快取,不管是否存在,仍然請求網路 CacheMode.FIRST_CACHE_THEN_REQUEST
無快取時,網路請求成功 onBefore -> onCacheError -> convertSuccess -> onSuccess -> onAfter
無快取時,網路請求失敗 onBefore -> onCacheError -> parseError -> onError -> onAfter
有快取時,網路請求成功 onBefore -> onCacheSuccess -> convertSuccess -> onSuccess -> onAfter
有快取時,網路請求失敗 onBefore -> onCacheSuccess -> parseError -> onError -> onAfter
1.基本的網路請求
OkGo.get(Urls.URL_METHOD) // 請求方式和請求 url
.tag(this) // 請求的 tag, 主要用於取消對應的請求
.cacheKey("cacheKey") // 設定當前請求的快取 key,建議每個不同功能的請求設定一個
.cacheMode(CacheMode.DEFAULT) // 快取模式,詳細請看快取介紹
.execute(new StringCallback() {
@Override
public void onSuccess(String s, Call call, Response response) {
// s 即為所需要的結果
}
});
2.請求 Bitmap 物件
OkGo.get(Urls.URL_IMAGE)//
.tag(this)//
.execute(new BitmapCallback() {
@Override
public void onSuccess(Bitmap bitmap, Call call, Response response) {
// bitmap 即為返回的圖片資料
}
});
3.請求 檔案下載
FileCallback
具有三個過載的構造方法,分別是
FileCallback()
:空參構造FileCallback(String destFileName)
:可以額外指定檔案下載完成後的檔名FileCallback(String destFileDir, String destFileName)
:可以額外指定檔案的下載目錄和下載完成後的檔名
檔案目錄如果不指定,預設下載的目錄為 sdcard/download/
,檔名如果不指定,則按照以下規則命名:
1.首先檢查使用者是否傳入了檔名,如果傳入,將以使用者傳入的檔名命名
2.如果沒有傳入,那麼將會檢查服務端返回的響應頭是否含有Content-Disposition=attachment;filename=FileName.txt
該種形式的響應頭,如果有,則按照該響應頭中指定的檔名命名檔案,如FileName.txt
3.如果上述響應頭不存在,則檢查下載的檔案 url,例如:http://image.baidu.com/abc.jpg
,那麼將會自動以abc.jpg
命名檔案
4.如果 url 也把檔名解析不出來,那麼最終將以nofilename
命名檔案
OkGo.get(Urls.URL_DOWNLOAD)//
.tag(this)//
.execute(new FileCallback() { //檔案下載時,可以指定下載的檔案目錄和檔名
@Override
public void onSuccess(File file, Call call, Response response) {
// file 即為檔案資料,檔案儲存在指定目錄
}
@Override
public void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
//這裡回撥下載進度(該回調在主執行緒,可以直接更新 ui)
}
});
4.普通 Post,直接上傳 String 型別的文字
一般此種用法用於與伺服器約定的資料格式,當使用該方法時,params 中的引數設定是無效的,所有引數均需要通過需要上傳的文字中指定,此外,額外指定的 header 引數仍然保持有效。
預設會攜帶以下請求頭
Content-Type: text/plain;charset=utf-8
如果你對請求頭有自己的要求,可以使用這個過載的形式,傳入自定義的content-type
upString("這是要上傳的長文字資料!", MediaType.parse("application/xml")) // 比如上傳 xml 資料,這裡就可以自己指定請求頭
OkGo.post(Urls.URL_TEXT_UPLOAD)//
.tag(this)//
// .params("param1", "paramValue1")// 這裡不要使用 params,upString 與 params 是互斥的,只有 upString 的���據會被上傳
.upString("這是要上傳的長文字資料!")//
// .upString("這是要上傳的長文字資料!", MediaType.parse("application/xml")) // 比如上傳 xml 資料,這裡就可以自己指定請求頭
.execute(new StringCallback() {
@Override
public void onSuccess(String s, Call call, Response response) {
//上傳成功
}
@Override
public void upProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
//這裡回撥上傳進度(該回調在主執行緒,可以直接更新 ui)
}
});
5.普通 Post,直接上傳 Json 型別的文字
該方法與 postString 沒有本質區別,只是資料格式是 json,一般來說,需要自己建立一個實體 bean 或者一個 map,把需要的引數設定進去,然後通過三方的 Gson 或者 fastjson 轉換成 json 字串,最後直接使用該方法提交到伺服器。
預設會攜帶以下請求頭,請不要手動修改,okgo 也不支援自己修改
Content-Type: application/json;charset=utf-8
HashMap<String, String> params = new HashMap<>();
params.put("key1", "value1");
params.put("key2", "這裡是需要提交的 json 格式資料");
params.put("key3", "也可以使用三方工具將物件轉成 json 字串");
params.put("key4", "其實你怎麼高興怎麼寫都行");
JSONObject jsonObject = new JSONObject(params);
OkGo.post(Urls.URL_TEXT_UPLOAD)//
.tag(this)//
// .params("param1", "paramValue1")// 這裡不要使用 params,upJson 與 params 是互斥的,只有 upJson 的資料會被上傳
.upJson(jsonObject.toString())//
.execute(new StringCallback() {
@Override
public void onSuccess(String s, Call call, Response response) {
//上傳成功
}
@Override
public void upProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
//這裡回撥上傳進度(該回調在主執行緒,可以直接更新 ui)
}
});
6.上傳圖片或者檔案
上傳檔案支援檔案與引數一起同時上傳,也支援一個 key 上傳多個檔案,以下方式可以任選
特別要注意的是
1).很多人會說需要在上傳檔案到時候,要把Content-Type
修改掉,變成multipart/form-data
,就像下面這樣的。其實在使用 OkGo 的時候,只要你添加了檔案,這裡的的Content-Type
不需要你手動設定,OkGo 自動新增該請求頭,同時,OkGo 也不允許你修改該請求頭。
Content-Type: multipart/form-data; boundary=f6b76bad-0345-4337-b7d8-b362cb1f9949
2).如果沒有檔案,那麼 OkGo 將自動使用以下請求頭,同樣 OkGo 也不允許你修改該請求頭。
Content-Type: application/x-www-form-urlencoded
3).如果你的伺服器希望你在沒有檔案的時候依然使用multipart/form-data
請求,那麼可以使用.isMultipart(true)
這個方法強制修改,一般來說是不需要強制的。
OkGo.post(URL_FORM_UPLOAD)//
.tag(this)//
.isMultipart(true) // 強制使用 multipart/form-data 表單上傳(只是演示,不需要的話不要設定。預設就是 false)
.params("param1", "paramValue1") // 這裡可以上傳引數
.params("file1", new File("filepath1")) // 可以新增檔案上傳
.params("file2", new File("filepath2")) // 支援多檔案同時新增上傳
.addFileParams("key", List<File> files) // 這裡支援一個 key 傳多個檔案
.execute(new StringCallback() {
@Override
public void onSuccess(String s, Call call, Response response) {
//上傳成功
}
@Override
public void upProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
//這裡回撥上傳進度(該回調在主執行緒,可以直接更新 ui)
}
});
7.https 請求,需要在初始化的時候配置以下程式碼
OkGo.getInstance()
...
//可以設定 https 的證書,以下幾種方案根據需要自己設定
.setCertificates() //方法一:信任所有證書,不安全有風險
// .setCertificates(new SafeTrustManager()) //方法二:自定義信任規則,校驗服務端證書
// .setCertificates(getAssets().open("srca.cer")) //方法三:使用預埋證書,校驗服務端證書(自簽名證書)
//方法四:使用 bks 證書和密碼管理客戶端證書(雙向認證),使用預埋證書,校驗服務端證書(自簽名證書)
// .setCertificates(getAssets().open("xxx.bks"), "123456", getAssets().open("yyy.cer"))//
//配置 https 的域名匹配規則,詳細看 demo 的初始化介紹,不需要就不要加入,使用不當會導致 https 握手失敗
// .setHostnameVerifier(new SafeHostnameVerifier())
...
8.請求功能的所有配置講解
以下程式碼包含了以下內容:
- 一次普通請求所有能配置的引數,真實使用時不需要配置這麼多,按自己的需要選擇性的使用即可
params
新增引數的時候,最後一個isReplace
為可選引數,預設為true
,即代表相同key
的時候,後新增的會覆蓋先前新增的- 多檔案和多引數的表單上傳,同時支援進度監聽
- 為單個請求設定超時,比如涉及到檔案的需要設定讀寫等待時間多一點。
OkGo.post(Urls.URL_METHOD) // 請求方式和請求 url, get 請求不需要拼接引數,支援 get,post,put,delete,head,options 請求
.tag(this) // 請求的 tag, 主要用於取消對應的請求
.isMultipart(true) // 強制使用 multipart/form-data 表單上傳(只是演示,不需要的話不要設定。預設就是 false)
.connTimeOut(10000) // 設定當前請求的連線超時時間
.readTimeOut(10000) // 設定當前請求的讀取超時時間
.writeTimeOut(10000) // 設定當前請求的寫入超時時間
.cacheKey("cacheKey") // 設定當前請求的快取 key,建議每個不同功能的請求設定一個
.cacheTime(5000) // 快取的過期時間,單位毫秒
.cacheMode(CacheMode.FIRST_CACHE_THEN_REQUEST) // 快取模式,詳細請看第四部分,快取介紹
.addInterceptor(interceptor) // 新增自定義攔截器
.headers("header1", "headerValue1") // 新增請求頭引數
.headers("header2", "headerValue2") // 支援多請求頭引數同時新增
.params("param1", "paramValue1") // 新增請求引數
.params("param2", "paramValue2") // 支援多請求引數同時新增
.params("file1", new File("filepath1")) // 可以新增檔案上傳
.params("file2", new File("filepath2")) // 支援多檔案同時新增上傳
.addUrlParams("key", List<String> values) // 這裡支援一個 key 傳多個引數
.addFileParams("key", List<File> files) // 這裡支援一個 key 傳多個檔案
.addFileWrapperParams("key", List<HttpParams.FileWrapper> fileWrappers)//這裡支援一個 key 傳多個檔案
//這裡給出的泛型為 ServerModel,同時傳遞一個泛型的 class 物件,即可自動將資料結果轉成物件返回
.execute(new DialogCallback<ServerModel>(this) {
@Override
public void onBefore(BaseRequest request) {
// UI 執行緒 請求網路之前呼叫
// 可以顯示對話方塊,新增/修改/移除 請求引數
}
@Override
public ServerModel convertSuccess(Response response) throws Exception{
// 子執行緒,可以做耗時操作
// 根據傳遞進來的 response 物件,把資料解析成需要的 ServerModel 型別並返回
// 可以根據自己的需要,丟擲異常,在 onError 中處理
return null;
}
@Override
public void parseError(Call call, IOException e) {
// 子執行緒,可以做耗時操作
// 用於網路錯誤時在子執行緒中執行資料耗時操作,子類可以根據自己的需要重寫此方法
}
@Override
public void onSuccess(ServerModel serverModel, Call call, Response response) {
// UI 執行緒,請求成功後回撥
// ServerModel 返回泛型約定的實體型別引數
// call 本次網路的請求資訊,如果需要檢視請求頭或請求引數可以從此物件獲取
// response 本次網路訪問的結果物件,包含了響應頭,響應碼等
}
@Override
public void onCacheSuccess(ServerModel serverModel, Call call) {
// UI 執行緒,快取讀取成功後回撥
// serverModel 返回泛型約定的實體型別引數
// call 本次網路的請求資訊
}
@Override
public void onError(Call call, Response response, Exception e) {
// UI 執行緒,請求失敗後回撥
// call 本次網路的請求物件,可以根據該物件拿到 request
// response 本次網路訪問的結果物件,包含了響應頭,響應碼等
// e 本次網路訪問的異常資訊,如果伺服器內部發生了錯誤,響應碼為 404,或大於等於 500
}
@Override
public void onCacheError(Call call, Exception e) {
// UI 執行緒,讀取快取失敗後回撥
// call 本次網路的請求物件,可以根據該物件拿到 request
// e 本次網路訪問的異常資訊,如果伺服器內部發生了錯誤,響應碼為 404,或大於等於 500
}
@Override
public void onAfter(ServerModel serverModel, Exception e) {
// UI 執行緒,請求結束後回撥,無論網路請求成功還是失敗,都會呼叫,可以用於關閉顯示對話方塊
// ServerModel 返回泛型約定的實體型別引數,如果網路請求失敗,該物件為 null
// e 本次網路訪問的異常資訊,如果伺服器內部發生了錯誤,響應碼為 404,或大於等於 500
}
@Override
public void upProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
// UI 執行緒,檔案上傳過程中回撥,只有請求方式包含請求體才回調(GET,HEAD 不會回撥)
// currentSize 當前上傳的大小(單位位元組)
// totalSize 需要上傳的總大小(單位位元組)
// progress 當前上傳的進度,範圍 0.0f ~ 1.0f
// networkSpeed 當前上傳的網速(單位秒)
}
@Override
public void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
// UI 執行緒,檔案下載過程中回撥
//引數含義同 上傳相同
}
});
9.取消請求
每個請求前都設定了一個引數tag
,取消則通過OkGo.cancel(tag)
執行。 例如:在 Activity 中,當 Activity 銷燬取消請求,可以在 onDestory 裡面統一取消。
@Override
protected void onDestroy() {
super.onDestroy();
//根據 Tag 取消請求
OkGo.getInstance().cancelTag(this);
//取消所有請求
OkGo.getInstance().cancelAll();
}
10.同步的請求
execute 方法不傳入 callback 即為同步的請求,返回Response
物件,需要自己解析
Response response = OkGo.get("http://www.baidu.com")//
.tag(this)//
.headers("aaa", "111")//
.params("bbb", "222")
.execute();
11.引數的順序
新增 header 和 param 的方法各有三個地方,在提交的時候,他們是有順序的,如果對提交順序有需要的話,請注意這裡
- 第一個地方,全域性初始化時,使用
OkGo.getInstance().addCommonHeaders()
,OkGo.getInstance().addCommonParams()
新增
HttpHeaders headers = new HttpHeaders();
headers.put("HKAAA", "HVAAA");
headers.put("HKBBB", "HVBBB");
HttpParams params = new HttpParams();
params.put("PKAAA", "PVAAA");
params.put("PKBBB", "PVBBB");
OkGo.getInstance()
.addCommonHeaders(headers) //設定全域性公共頭
.addCommonParams(params); //設定全域性公共引數
- 第二個地方,
callback
的onBefore
方法中新增
public abstract class CommonCallback<T> extends AbsCallback<T> {
@Override
public void onBefore(BaseRequest request) {
super.onBefore(request);
request.headers("HKCCC", "HVCCC")//
.headers("HKDDD", "HVDDD")//
.params("PKCCC", "PVCCC")//
.params("PKDDD", "PVDDD")//
}
}
- 第三個地方,執行網路請求的時候新增
OkGo.get(Urls.URL_METHOD)//
.tag(this)//
.headers("HKEEE", "HVEEE")//
.headers("HKFFF", "HVFFF")//
.params("PKEEE", "PVEEE")//
.params("PKFFF", "PVFFF")//
.execute(new MethodCallBack<>(this, ServerModel.class));
那麼,最終執行請求的引數的新增順序為
- Header 順序: HKAAA -> HKBBB -> HKEEE -> HKFFF -> HKCCC -> HKDDD
- Params 順序: PKAAA -> PKBBB -> PKEEE -> PKFFF -> PKCCC -> PKDDD
總結一句話就是,全域性新增的在最開始,callback 新增的在最後,請求新增的在中間
三、自定義 CallBack 使用
目前內部提供的包含AbsCallback
, StringCallBack
,BitmapCallback
,FileCallBack
,可以根據自己的需求去自定義 Callback
AbsCallback
: 所有回撥的父類,抽象類StringCallBack
:如果返回值型別是純文字資料,即可使用該回調BitmapCallback
:如果請求的是圖片資料,則可以使用該回調FileCallBack
:如果要做檔案下載,則必須使用該回調,內部封裝了關於檔案下載進度回撥的方法
該網路框架的核心使用方法即為Callback
的繼承使用,詳細請看 Demo 原始碼中callback
包下的程式碼。
因為不同的專案需求,可能對資料格式進行了不同的封裝,於是在 Demo 中的進行了詳細的程式碼示例,以下是詳細介紹:
JsonCallback
:繼承自AbsCallback
,一般來說,伺服器返回的響應碼都包含 code,msg,data 三部分,在此根據自己的業務需要完成相應的邏輯判斷,並對資料進行解析,可以使用Gson
或者fastjson
,將解析的物件返回。DialogCallback
:繼承自JsonCallback
,對需要在網路請求的時候顯示對話方塊,使用該回調。StringDialogCallback
:繼承自EncryptCallback
,如果網路返回的資料只是純文字,使用該回調BitmapDialogCallback
:繼承自BitmapCallback
,如果網路返回的是 Bitmap 物件,使用該回調DownloadFileCallBack
:繼承自FileCallback
,如果需要做檔案下載,使用該回調
以上基本是包含了大部分的業務邏輯,具體情況請參照 demo 示例,根據業務需求修改!
四、快取的使用
使用快取前,必須讓快取的資料javaBean
物件實現Serializable
介面,否者會報NotSerializableException
。
因為快取的原理是將物件序列化後直接寫入 資料庫中,如果不實現Serializable
介面,會導致物件無法序列化,進而無法寫入到資料庫中,也就達不到快取的效果。
對於DEFAULT
快取模式,超時時間是無效的,因為該模式是完全遵循標準的 http 協議的,快取時間是依靠服務端響應頭來控制,所以客戶端的 cacheTime 引數無效
目前提供了五種CacheMode
快取模式,每種快取模式都可以指定對應的CacheTime
,不同的模式會有不同的方法回撥順序,詳細請看上面第二部分的 callback 執行順序
NO_CACHE
: 不使用快取,該模式下,cacheKey
,cacheTime
引數均無效DEFAULT
: 按照 HTTP 協議的預設快取規則,例如有 304 響應頭時快取。REQUEST_FAILED_READ_CACHE
:先請求網路,如果請求網路失敗,則讀取快取,如果讀取快取失敗,本次請求失敗。IF_NONE_CACHE_REQUEST
:如果快取不存在才請求網路,否則使用快取。