從今天開(kāi)始跌榔,我決定做一件有意義的事异雁,逐步開(kāi)源一些我認(rèn)為很有價(jià)值的項(xiàng)目并附帶一些深度的原理分析。給那些想要提高android開(kāi)發(fā)技術(shù)水平僧须,但又沒(méi)有思路的同學(xué)一些方法上的啟迪纲刀。同時(shí)也可以宏觀上擴(kuò)展個(gè)人的技術(shù)視野和眼界。下面開(kāi)始第一個(gè)開(kāi)源項(xiàng)目的深度講解担平,大家一起來(lái)吧示绊。
項(xiàng)目名稱DDNetCore,封裝這個(gè)框架的主要目的是簡(jiǎn)化網(wǎng)絡(luò)數(shù)據(jù)的獲取,解析過(guò)程暂论,讓業(yè)務(wù)開(kāi)發(fā)者從處理網(wǎng)絡(luò)數(shù)據(jù)獲取的復(fù)雜事務(wù)中解脫出來(lái)面褐,將更多的關(guān)注點(diǎn)放在業(yè)務(wù)邏輯的開(kāi)發(fā)上面。
項(xiàng)目git地址:https://github.com/jessie345/DDNetCore
下面我嘗試以一種更容易理解的方式說(shuō)明這個(gè)框架的使用方式和工作原理取胎。首先來(lái)一張框架流程圖展哭,可以從宏觀的角度理解下框架內(nèi)部交互的大體過(guò)程。
現(xiàn)在扼菠,我們按照流程圖描述的執(zhí)行順序摄杂,逐步闡述框架的使用方式及原理。
發(fā)起數(shù)據(jù)請(qǐng)求的第一步需要實(shí)例化請(qǐng)求對(duì)象循榆,并塞給RequestManager 執(zhí)行析恢。原生的方式需要為不同的請(qǐng)求創(chuàng)建不同的Request子類(lèi),子類(lèi)中處理請(qǐng)求相關(guān)的邏輯(覆寫(xiě)相關(guān)的回掉方法)并實(shí)例化秧饮。但是這種方式帶來(lái)一個(gè)問(wèn)題映挂,對(duì)于大多數(shù)請(qǐng)求泽篮,請(qǐng)求及響應(yīng)結(jié)果的處理邏輯基本相同,為了減少創(chuàng)建子類(lèi)的重復(fù)勞動(dòng)柑船,網(wǎng)絡(luò)庫(kù)提供了DataRequestBuilder 構(gòu)建器帽撑,通過(guò)他,可以創(chuàng)建通用的對(duì)象請(qǐng)求(返回結(jié)果可以對(duì)等一個(gè)bean)鞍时,列表請(qǐng)求實(shí)例(返回結(jié)果可以對(duì)比成List<Bean>)亏拉。這個(gè)模式極大的簡(jiǎn)化了發(fā)起請(qǐng)求需要執(zhí)行的前期工作,讓你編寫(xiě)數(shù)據(jù)接口的工作相當(dāng)簡(jiǎn)單逆巍,我舉個(gè)例子:
Request request = DataRequestBuilder.asArrayRequest("/products")
.requestId(REQUEST_FETCH_PRODUCTS)
.requestDefaultStrategy(Constants.STRATEGY_LEVEL3_CACHE)
.requestExpireStrategy(Constants.STRATEGY_REFRESH_CACHE)
.memoryCache()
.dbCache()
.dataClass(ProductBean.class)
.httpMethod(Constants.HTTP_METHOD_GET)
.build();
上面幾行代碼創(chuàng)建了一個(gè)獲取產(chǎn)品列表的數(shù)據(jù)請(qǐng)求及塘,第一行代碼指定了創(chuàng)建一個(gè)路徑為/products的數(shù)組請(qǐng)求,即服務(wù)器返回的數(shù)據(jù)是個(gè)列表锐极。第二行代碼為請(qǐng)求指定了id笙僚,通過(guò)這個(gè)id,我在響應(yīng)回調(diào)里可以非常容易的區(qū)分哪個(gè)請(qǐng)求的結(jié)果返回了灵再。第三第四行代碼分別指明了默認(rèn)情況和請(qǐng)求響應(yīng)結(jié)果過(guò)期情況的請(qǐng)求執(zhí)行策略,框架提供三種數(shù)據(jù)請(qǐng)求策略肋层,分別為:Constants.STRATEGY_LEVEL3_CACHE(三級(jí)緩存策略),Constants.STRATEGY_REFRESH_CACHE(強(qiáng)制刷新緩存策略)翎迁,Constants.STRATEGY_ONLY_NET(強(qiáng)制請(qǐng)求網(wǎng)絡(luò)策略)栋猖。第五行第六行指定請(qǐng)求是否使用內(nèi)存和數(shù)據(jù)庫(kù)緩存。第七行指定用哪個(gè)class反序列化服務(wù)器返回的數(shù)據(jù)汪榔。倒數(shù)第二行指定了請(qǐng)求的執(zhí)行方式為get,框架同時(shí)內(nèi)置了對(duì)兩種基本請(qǐng)求方式的支持,Constants.HTTP_METHOD_GET(基本get請(qǐng)求方式),Constants.HTTP_METHOD_POST(post 請(qǐng)求方式掂铐,post的content-type可以為application/json,www-form-urlencoded)
有了request實(shí)例,我們可以將它交給RequestManager執(zhí)行了揍异。我在BaseActivity中封裝了如下代碼:
public void enqueueRequest(Request request) {
if (!mNetworkControl.isControlListenerRegistered(this)) {
mNetworkControl.registerControlListener(this);
}
mNetworkControl.enqueueRequest(request);
}
通過(guò)NetWorkControl實(shí)例,將請(qǐng)求交給RequestManager執(zhí)行爆班,NetWorkControl中會(huì)執(zhí)行一些與取消請(qǐng)求相關(guān)的邏輯衷掷。
請(qǐng)求已經(jīng)提交到線程池執(zhí)行,那么我們?nèi)绾谓邮辗祷氐臄?shù)據(jù)結(jié)果呢柿菩。NetworkControl 類(lèi)提供了獲取響應(yīng)結(jié)果的監(jiān)聽(tīng)函數(shù):
public void registerControlListener(@NonNull NetworkControlListener listener) {
Preconditions.checkNotNull(listener);
this.mListenerRef = new WeakReference(listener);
}
注冊(cè)監(jiān)聽(tīng)后戚嗅,通過(guò)如下三個(gè)與請(qǐng)求生命周期相關(guān)的回調(diào),就可以獲取請(qǐng)求及響應(yīng)的相關(guān)信息啦枢舶。
public void handlePreNetRequest(@NonNull Request request) {
}
@Override
public void handleNetRequestError(@NonNull Request request, @NonNull ResponseHeader rb) {
}
@Override
public void handleReceivedResponse(@NonNull EventResponse event) {
}
handlePreNetRequest 表示某個(gè)請(qǐng)求即將添加到請(qǐng)求隊(duì)列執(zhí)行懦胞。handleNetRequestError 表示某個(gè)請(qǐng)求發(fā)生了錯(cuò)誤。handleReceivedResponse 表示請(qǐng)求的結(jié)果正確返回凉泄。通過(guò)這三個(gè)方法就能判斷Request的執(zhí)行狀態(tài)了躏尉。
體會(huì)一下,寫(xiě)一個(gè)請(qǐng)求接口是不是很簡(jiǎn)單后众。
如果想了解更多信息或者對(duì)開(kāi)源項(xiàng)目感興,請(qǐng)加我的微信公眾號(hào)胀糜,我在那里等你