由于NoHttpRxUtils是通過RxJava對NoHttp網(wǎng)絡框架操作進行一系列封裝。
首先對RxJava和NoHttp網(wǎng)絡框架做一個簡介
RxJava框架是什么?
RxJava是響應式程序設計的一種實現(xiàn)。
在響應式程序設計中,當數(shù)據(jù)到達的時候,消費者做出響應。
響應式編程可以將事件傳遞給注冊了的observer。
NoHttp框架是什么?
Nohttp是一個專門針對Android網(wǎng)絡通訊的框架
Nohttp框架特性
比Retrofit使用更簡單、更易用。
動態(tài)配置底層框架為OkHttp、HttpURLConnection
支持異步請求、支持同步請求
多文件上傳,支持大文件上傳,表單提交數(shù)據(jù)
文件下載、上傳下載、上傳和下載的進度回調(diào)、錯誤回調(diào)
支持Json、xml、Map、List的提交
完美的Http緩存模式,可指定緩存到數(shù)據(jù)庫、SD卡,緩存數(shù)據(jù)已安全加密
自定義Request,直接請求JsonObject、JavaBean等
Cookie的自動維持,App重啟、關開機后還持續(xù)維持
http 301 302 303 304 307重定向,支持多層嵌套重定向
Https、自簽名網(wǎng)站Https的訪問、支持雙向驗證
失敗重試機制,支持請求優(yōu)先級
GET、POST、PUT、PATCH、HEAD、DELETE、OPTIONS、TRACE等請求協(xié)議
用隊列保存請求,平均分配多線程的資源,支持多個請求并發(fā)
支持取消某個請求、取消指定多個請求、取消所有請求
支持斷點續(xù)傳和斷點處繼續(xù)下載
NoHttpRxUtils框架是什么?
NoHttpRxUtils主要是通過RxJava框架對NoHttp網(wǎng)絡框架操作進行再次封裝。
減輕使用者繁瑣的調(diào)用,讓使用者更專注于項目業(yè)務,而非客戶端與服務器之間的網(wǎng)絡通訊。
由于NoHttpRxUtils網(wǎng)絡請求方面是采用NoHttp同步請求,所以請求隊列不是NoHttp隊列算法而是NoHttpRxUtils隊列算法。
暫時不支持隊列請求優(yōu)先級設置。如果要想讓一個請求優(yōu)先,可以使用Rx線程單一請求。
由于Android系統(tǒng)對SD卡寫入權限的約束,所以所有的緩存數(shù)據(jù)路徑都指向于數(shù)據(jù)庫。
NoHttpRxUtils框架功能
* ?框架初始化、網(wǎng)絡請求、文件下載調(diào)用方式全采用鏈式。
* 數(shù)據(jù)請求方面,支持RxJava線程隊列請求和Rx線程單一請求。
* RxJava線程隊列請求=>通過算法實現(xiàn)線程池對RxJava框架線程進行管理和操作,支持撤銷單個請求、多個請求,指定請求。
* Rx線程單一請求=>直接開啟一個RxJava線程,不進行隊列優(yōu)先直接請求。
* 文件下載,下載隊列是NoHttp隊列算法。針對NoHttp數(shù)據(jù)下載進行Android-Service捆綁封裝,支持單個下載任務取消(暫停)、多個下載任務取消、單個下載任務恢復(開始)、多個下載任務恢復(開始)。
* 支持自動通過指定對象去得到服務器數(shù)據(jù)。Json格式數(shù)據(jù)轉換層采用Gson框架轉換(轉換對象中定義的數(shù)據(jù)結構必須要符合Json數(shù)據(jù)結構)
* 支持輪詢請求,支持撤銷單個輪詢請求、多個輪詢請求、指定輪詢請求。
* 支持使用其它網(wǎng)絡框架去輪詢請求
NoHttpRxUtils框架-RxJava-1版-Github鏈接(李奇)
NoHttpRxUtils框架-RxJava-2版-Github鏈接(李奇)
一個框架開始之前是不是應該去初始化呢?
對,沒錯?,F(xiàn)在我就教你NoHttpRxUtils去如何初始化
鏈式初始化NoHttp,建議放到Application中onCreate生命周期方法里面
//初始化NoHttp(在此處其實可以調(diào)用setDialogGetListener設置全局請求加載框)
RxNoHttpUtils.rxNoHttpInit(getApplicationContext())
//是否維護Cookie
.setCookieEnable(false)
//是否緩存進數(shù)據(jù)庫DBCacheStore
.setDbEnable(true)
//是否開啟debug調(diào)試
.isDebug(true)
//設置debug打印Name
.setDebugName("LiQi-NoHttpUtils")
//設置全局連接超時時間。單位秒,默認30s。
.setConnectTimeout(40)
//設置全局服務器響應超時時間,單位秒,默認30s。
.setReadTimeout(40)
//設置下載線程池并發(fā)數(shù)量(默認并發(fā)數(shù)量是3)
.setThreadPoolSize(3)
//設置網(wǎng)絡請求隊列并發(fā)數(shù)量(默認并發(fā)數(shù)量是3)
.setRunRequestSize(4)
//設置全局默認加載對話框?。注:不允許在此方法里面創(chuàng)建dialog對象。
.setDialogGetListener("全局加載框獲取接口")
//設置底層用那種方式去請求
.setRxRequestUtilsWhy(NoHttpInit.OKHTTP)
//設置全局帶證書安全協(xié)議請求(如果在請求調(diào)用的時候切換了安全協(xié)議方式,允許覆蓋此設置)
.setInputStreamSSL(new InputStream())
//設置全局無證書安全協(xié)議請求(如果在請求調(diào)用的時候切換了安全協(xié)議方式,允許覆蓋此設置)
.setInputStreamSSL()
//添加全局請求頭
.addHeader("app>>head","app_head_global")
//添加全局請求參數(shù)-只支持String類型
.addParam("app_param","app_param_global")
//設置Cookie管理監(jiān)聽。
.setCookieStoreListener(new DBCookieStore.CookieStoreListener())
//設置全局主機驗證(如果在請求調(diào)用的時候切換了無證書安全協(xié)議方式,此設置失效)
.setHostnameVerifier(new HostnameVerifier())
//設置全局重試次數(shù),配置后每個請求失敗都會重試設置的次數(shù)。
.setRetry(5)
//設置全局請求網(wǎng)絡出現(xiàn)未知錯誤提示語
.setAnUnknownErrorHint("全局未知錯誤提示語")
//開始初始化NoHttp
.startInit()
初始化就是這么簡單,就問你驚不驚喜,意不意外。
初始化需要注意的事項:
1:通過setDialogGetListener()設置對話框時候,對話框依賴的context必須是棧頂context
2:當初始化時通過setHostnameVerifier()/設置全局主機驗證,但是如果在請求調(diào)用的時候切換了無證書安全協(xié)議方式,此設置失效。
來來來,我來講講如何使用NoHttpRxUtils去數(shù)據(jù)下載!
下載開啟(又是鏈式調(diào)用)
//獲取下載請求構建器
NoHttpDownloadUtils.getNoHttpDownloadBuild()
//添加下載文件參數(shù)
.addDownloadParameter(DOWNLOAD_FILE01, "Liqi_single_test.apk")
//設置是否斷點續(xù)傳下載
.setRange(true)
//設置下載進度監(jiān)聽接口
.setDownloadListener(this)
//設置在指定的文件夾發(fā)現(xiàn)同名的文件是否刪除后重新下載
.setDeleteOld(false)
//設置下載文件存儲文件路徑
.setFileFolder(FILEPATH)
//單個請求設置讀取時間(單位秒,默認以全局讀取超時時間。)
.setReadTimeout(40)
//單個請求設置鏈接超時時間(單位秒,默認以全局鏈接超時時間。)
.setConnectTimeout(40)
//單個請求設置請求失敗重試計數(shù)。默認值是0,也就是說,失敗后不會再次發(fā)起請求。
.setRetryCount(3)
//開啟下載
.satart(this)
下載暫停(取消)
//暫停全部正在下載任務
NoHttpDownloadUtils.cancelAll();
//暫停指定下載任務
NoHttpDownloadUtils.cancel(downloadUrl);
有暫停,那必須就得有恢復。
//恢復指定下載
NoHttpDownloadUtils.startRequest(downloadUrl);
//恢復全部下載
NoHttpDownloadUtils.startAllRequest();
當你覺得所有連接下載沒用了,那么你也是可以全部取消的哦!
//清空當前下載請求對象,并停止服務
NoHttpDownloadUtils.clearAll();
你也可以對下載Url對應的what值進行操作
//獲取下載URL對象的What值
NoHttpDownloadUtils.getDownloadRequestsWhat(downloadUrl);
//移除下載URL對應的What
NoHttpDownloadUtils.removeWhatData(downloadUrl);
//移除全部下載What
NoHttpDownloadUtils.removeWhatAll();
下載注意事項:
如果上一次下載任務沒有完成或者沒有清空,那么下一次點擊任何下載都會繼續(xù)執(zhí)行上一次沒有完成的任務繼續(xù)下載
這一次講講如何使用NoHttpRxUtils去數(shù)據(jù)請求!
NoHttpRxUtils網(wǎng)絡請求(還是鏈式調(diào)用)
//獲取請求對象
RxNoHttpUtils.rxNoHttpRequest()
//get請求方式(除了get和post請求,還支持put,delete,head,patch,options,trace)
.get()
//post請求方式(除了get和post請求,還支持put,delete,head,patch,options,trace)
.post()
//設置Url
.url("url")
//添加請求參數(shù)
//當傳入的參數(shù)類型不屬于內(nèi)部設定類型時,默認調(diào)用Object的toString()轉換為String類型參數(shù)
.addParameter()
//添加請求頭
.addHeader()
//設置請求bodyEntity為StringEntity,并傳請求類型。
.requestStringEntity(Content-Type)
//為StringEntity添加body中String值
.addStringEntityParameter("請求的String")
//從bodyEntity切換到請求配置對象
.transitionToRequest()
//設置請求bodyEntity為JsonObjectEntity.json格式:{"xx":"xxx","yy":"yyy"}
.requestJsonObjectEntity()
//給JsonObjectEntity添加參數(shù)和值
.addEntityParameter("key","Valu")
//從bodyEntity切換到請求配置對象
.transitionToRequest()
//設置請求bodyEntity為JsonListEntity.json格式:[{"xx":"xxx"},{"yy":"yyy"}]
.requestJsonListEntity()
//給JsonList創(chuàng)造對象,并傳鍵值參數(shù)
.addObjectEntityParameter("key","Valu")
//在創(chuàng)造對象的上添加鍵值參數(shù)
.addEntityParameter("key","Valu")
//把創(chuàng)造對象刷進進JsonList里面
.objectBrushIntoList()
//從bodyEntity切換到請求配置對象
.transitionToRequest()
//設置請求bodyEntity為InputStreamEntity
.requestInputStreamEntity(Content-Type)
//給InputStreamEntity添加輸入流
.addEntityInputStreamParameter(InputStream)
//從bodyEntity切換到請求配置對象
.transitionToRequest()
//單個請求設置讀取時間(單位秒,默認以全局讀取超時時間。)
.setReadTimeout(40)
//單個請求設置鏈接超時時間(單位秒,默認以全局鏈接超時時間。)
.setConnectTimeout(30)
//單個請求設置請求失敗重試計數(shù)。默認值是0,也就是說,失敗后不會再次發(fā)起請求。
.setRetryCount(3)
//單個請求設置緩存key
.setCacheKey("get請求Key")
//單個請求設置緩存模式(跟原生NoHttp五種緩存模式一致)
.setCacheMode(CacheMode.REQUEST_NETWORK_FAILED_READ_CACHE)
//設置當前請求是否添加進Rx"線程池"隊列中(默認是添加rx"線程池"中.!!如果設置false,請求線程不經(jīng)過Rx"線程池"直接請求)
.setQueue(false)
//設置Rx"線程池"隊列標識.(標識設置請保證唯一.!!如果setQueue(false)設置為false,setSign(標識對象)設置無任何作用)
.setSign(new Object())
//添加HTTPS協(xié)議無證書參數(shù)
.addHttpsIsCertificate()
//添加HTTPS協(xié)議有證書參數(shù)
.addHttpsIsCertificate(InputStream)
//設置請求圖片的最大寬高
.setBitmapMaxWH(500,500)
//設置請求位圖的配置和比例
.setBitmapConfigType(Bitmap.Config, ImageView.ScaleType)
//設置請求加載框(如果此處沒有設置加載框,那么就默認使用初始化設置的加載框) 。注:不允許在此方法里面創(chuàng)建dialog對象。
.setDialogGetListener(this)
//設置請求網(wǎng)絡出現(xiàn)未知錯誤提示語
.setAnUnknownErrorHint("未知錯誤提示語")
//創(chuàng)建請求對象,并指定響應轉換類型和請求成功或者失敗回調(diào)接口
.builder(Objects.class,new OnIsRequestListener)
//開始請求
.requestRxNoHttp();
這么"白癡"式的調(diào)用,是不是很驚訝!
請求注意事項:
1:BodyEntity內(nèi)部自動處理的格式只有兩種,json格式:{"xx":"xxx","yy":"yyy"}+json格式:[{"xx":"xxx"},{"yy":"yyy"}]。如果這兩種格式不滿足你的需求,你可以自己把BodyEntity的格式轉換字符串傳輸。
2:如果此方法setQueue(false)賦值為false的話,請求線程不經(jīng)過Rx"線程池隊列"直接請求。并且setSign(new Object())設置的值無效,也不可取消此請求。
3:如果使用addHttpsIsCertificate()HTTPS協(xié)議無證書參數(shù),那么設置全局主機驗證對這個請求失效
手動取消Rx"線程池"中隊列請求(setQueue(false)如果設置為false,手動取消將失去作用)
//單個取消Sign對應的請求
RxNoHttpUtils.cancel(Sign));
//取消批量Sign對應的請求
RxNoHttpUtils.cancel(Sign[]);
//取消RX"線程池"中所有的請求
// RxNoHttpUtils.cancelAll();
一個網(wǎng)絡框架怎么能沒有輪詢呢
來來來,看看NoHttpRxUtils去如何輪詢請求的。
NoHttpRxUtils輪詢請求,繼續(xù)采用鏈式調(diào)用
//獲取請求對象
RxNoHttpUtils.rxNoHttpRequest()
//NoHttp網(wǎng)絡請求設置參數(shù)跟上面一樣設置
...
//設置當前輪詢請求Sign
.setSign(new Object())
//創(chuàng)建輪詢請求對象,并指定響應轉換類型和請求成功或者失敗回調(diào)接口
.builderPoll(Objects.class,new OnIsRequestListener)
//設置初始化加載延遲
.setInitialDelay(3 * 1000)
//設置輪詢間隔時間-默認3秒
.setPeriod(5 * 1000)
//設置被觀察者產(chǎn)生的行為事件監(jiān)聽器-
//(如果此處實現(xiàn)被觀察者產(chǎn)生的行為事件監(jiān)聽器,那么框架內(nèi)部就不去維護此輪詢請求,必須實現(xiàn)輪詢攔截器接口去維護此輪詢什么時候停止。 RxNoHttpUtils.cancelPoll()取消輪詢將無效,設置內(nèi)部加載框?qū)o效 )
.setOnObserverEventListener(new OnObserverEventListener(){
@Override
public RxInformationModel onObserverEvent(RestRequest transferValue) {
? ? ? ?// RxInformationModel對象方法介紹
? ? ? ? //getData()=獲取請求數(shù)據(jù)
? ? ? ?//setData(T data)=賦值請求數(shù)據(jù)
? ? ? ?//setException(boolean exception)=賦值是否是異常狀態(tài)
? ? ? ?//isException()=獲取是否異常狀態(tài)
? ? ? ?//setThrowable(Throwable throwable)=賦值異常類
? ? ? ?//getThrowable()=獲取異常類
? ? ? ?//setStop(boolean stop)=賦值是否停止輪詢狀態(tài)
? ? ? ?//isStop()=獲取是否輪詢狀態(tài)
? ? ? ?//RxInformationModel 此對象需要new 出來.
? ? ? //在此方法中可以換成自己鐘意的網(wǎng)絡框架去請求,如果設置了網(wǎng)絡請求參數(shù),除 ? ? ? ? 了body其它的都能從RestRequest里面取得。
? return informationModel;
}
})
// 設置設置數(shù)據(jù)攔截監(jiān)聽對象
.setBooleanFunc1(new Func1() {
@Override
public Boolean call(RxInformationModel stringRxInformationModel) {
//在此方法里面可以根據(jù)RxInformationModel.getData()獲取請求的數(shù)據(jù),然后根據(jù)請求的數(shù)據(jù)來決定是否停止輪詢
return stringRxInformationModel.isStop();
} })
//設置觀察者根據(jù)被觀察產(chǎn)生的行為做出相應處理監(jiān)聽器
//如果實現(xiàn)了此接口,那么builderPoll中實現(xiàn)的OnIsRequestListener將無效。
.setRxInformationModelAction1(new Action1() {
@Override
public void call(RxInformationModel stringRxInformationModel) {
//在此方法里面根據(jù)RxInformationModel中的數(shù)據(jù)做出相應動作
}
})
//轉換成輪詢請求類
.switchPoll()
//開始請求
.requestRxNoHttp();
輪詢請求注意事項:
1:如果想停止輪詢請求,可以根據(jù)setSign(new Object())設置的值去手動取消輪詢請求,也可以根據(jù)setBooleanFunc1(new Func1())方法去賦值輪詢攔截器,在實現(xiàn)的方法里面可以根據(jù)RxInformationModel.getData()獲取請求的數(shù)據(jù),然后根據(jù)請求的數(shù)據(jù)來決定是否停止輪詢
2:如果通過setOnObserverEventListener(new OnObserverEventListener())方法去實現(xiàn)OnObserverEventListener對象,你可以在實現(xiàn)的方法里面換成自己鐘意的網(wǎng)絡框架去請求,如果設置了網(wǎng)絡請求參數(shù),除了body其它的都能從RestRequest里面取得。但是框架內(nèi)部就不去維護此輪詢請求,無法通過框架去停止此輪詢請求,必須實現(xiàn)輪詢攔截器接口去維護此輪詢什么時候停止。
3:如果通過setRxInformationModelAction1(new Action1())方法去賦值Action1,那么builderPoll中實現(xiàn)的OnIsRequestListener將無效。
如何取消輪詢請求?
//單個取消Sign對應的輪詢請求
RxNoHttpUtils.cancelPoll(Sign));
//取消批量Sign對應的輪詢請求
RxNoHttpUtils.cancelPoll(Sign[]);
//取消所有的輪詢請求
// RxNoHttpUtils.cancelPollAll();
如果你開啟了緩存,那么這里就教你清除緩存
//清除對應的key的緩存數(shù)據(jù)
RxNoHttpUtils.removeKeyCacheData("Cachekey");
//清除所有緩存數(shù)據(jù)
RxNoHttpUtils.removeAllCacheData();
下載下來的NohttpRxUtils項目結構

nohttputils是針對Nohttp請求進行封裝的工具,sample是調(diào)用nohttputils工具的demo。
所有Activity的基類BaseActivity

BaseActivity中實現(xiàn)了兩個接口:DialogGetInterfa,RequestOkAndNo<T>
DialogGetInterfa接口:網(wǎng)絡請求加載對話框獲取接口(nohttputils內(nèi)部定義的接口,不實現(xiàn)就不彈出加載對話框或者彈出初始化設置的默認加載框)

RequestOkAndNo<T>接口:網(wǎng)絡請求成功或者失敗的接口(nohttputils內(nèi)部定義的接口)

RequestOkAndNo<T>接口中兩個方法介紹
onNext(T response):由于返回的參數(shù)是泛型,就是代表任何類型都可以返回。!如果想把網(wǎng)絡返回的數(shù)據(jù)裝進指定的對象中,那么該對象的定義請按照Gson框架要求去定義。因為數(shù)據(jù)轉換那層,我是使用了Gson框架。(主線程運行)
onError(Throwable e):在nohttputils內(nèi)部做了一些錯誤捕捉提示,如還需自己提示的錯誤,請自己在實現(xiàn)此方法里面diy。(注:如果此網(wǎng)絡請求沒有設置加載對話框,那么就無法顯示nohttputils內(nèi)置的錯誤提示)(主線程運行)
其它Activity界面通過繼承BaseActivity,實現(xiàn)當前的界面業(yè)務和邏輯


當前Activity繼承BaseActivity,通過指定當前網(wǎng)絡請求成功返回的數(shù)據(jù)類型。網(wǎng)絡請求成功后可以在onNext回調(diào)方法里面做自己相應的邏輯和界面控件操作