NoHttpRxUtils網(wǎng)絡通訊框架讓使用者更專注于項目業(yè)務,而非客戶端與服務器之間的網(wǎng)絡通訊。

由于NoHttpRxUtils是通過RxJava對NoHttp網(wǎng)絡框架操作進行一系列封裝。

首先對RxJava和NoHttp網(wǎng)絡框架做一個簡介

RxJava框架是什么?


RxJava是響應式程序設計的一種實現(xiàn)。

在響應式程序設計中,當數(shù)據(jù)到達的時候,消費者做出響應。

響應式編程可以將事件傳遞給注冊了的observer。

RxJava框架GitHub鏈接(ReactiveX)

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ù)下載

NoHttp框架GitHub鏈接(嚴振杰)

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項目結構

NohttpRxUtils項目結構

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

所有Activity的基類BaseActivity

所有Activity的基類BaseActivity

BaseActivity中實現(xiàn)了兩個接口:DialogGetInterfa,RequestOkAndNo<T>

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


DialogGetInterfa接口


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


RequestOkAndNo接口

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
Activity界面網(wǎng)絡請求成功回調(diào)

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

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容