欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android斬首行動接口預(yù)請求

 更新時間:2023年03月03日 08:58:50   作者:孝之請回答  
這篇文章主要為大家介紹了Android斬首行動之接口預(yù)請求實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

開發(fā)同學(xué)應(yīng)該都很熟悉我們頁面的渲染過程一般是從Activity#onCreate開始,再發(fā)起網(wǎng)絡(luò)請求,等請求回調(diào)回來后,再基于網(wǎng)絡(luò)數(shù)據(jù)渲染頁面。可以用下面這幅圖來粗略描述這個過程:

可以看到,目標(biāo)頁面渲染完成前必須得等待網(wǎng)絡(luò)請求,導(dǎo)致渲染速度并沒有那么快。尤其是當(dāng)網(wǎng)絡(luò)并不好的時候感受會更加明顯。并且,當(dāng)目標(biāo)頁面是H5頁面或者是Flutter頁面的時候,因為涉及到H5容器與Flutter容器的創(chuàng)建,白屏?xí)r間會更長。

那么有沒有可能提前發(fā)起請求,來縮短網(wǎng)絡(luò)請求這一部分的等待時間呢?這就是我們今天要講的部分,接口預(yù)請求。

目標(biāo)

我們要達到的目標(biāo)很簡單,就是提前異步發(fā)起目標(biāo)頁面的網(wǎng)絡(luò)請求,從而加快目標(biāo)頁面的渲染速度。改善后的過程可以用下圖表示:

并且,我們的預(yù)請求能力需要盡量少地侵入業(yè)務(wù),與業(yè)務(wù)解耦,并保證能力的通用性,適用于工程內(nèi)的任意頁面(Android頁面、H5頁面、Flutter頁面)。

整體鏈路

首先給大家看一下整體鏈路,具體的細節(jié)可以先不用去摳,下面會一一講到。

預(yù)請求時機

預(yù)請求時機一般有三種選擇:

  • 由業(yè)務(wù)層自行選擇時機進行異步預(yù)請求
  • 點擊控件時進行異步預(yù)請求
  • 路由最終跳轉(zhuǎn)前進行異步預(yù)請求

第1種選擇,由業(yè)務(wù)層自行選擇時機進行預(yù)請求,需要涉及到業(yè)務(wù)層的改造,以及對時機合理性的把握。一方面是存在改造成本,另一方面是無法保證業(yè)務(wù)側(cè)調(diào)用時機的合理性。

第2種選擇,點擊控件時進行預(yù)請求。若點擊時進行預(yù)請求,點擊事件監(jiān)聽并不是業(yè)務(wù)域統(tǒng)一的,無法形成有效封裝。并且,若后續(xù)路由攔截器修改了參數(shù),或是終止了跳轉(zhuǎn),這次預(yù)請求就失去了意義。

因此這里我們選擇第3種,基于統(tǒng)一路由框架,在路由最終跳轉(zhuǎn)前進行預(yù)請求。既保證了良好的封裝性,也實現(xiàn)了對業(yè)務(wù)的零侵入,同時也做到了懶請求,即用戶必然要發(fā)起該請求時才會去預(yù)請求。這里需要注意的是必須是在最終跳轉(zhuǎn)前進行預(yù)請求,可以理解為是路由的最后一個前置異步攔截器。

預(yù)請求規(guī)則配置

我們通過本地的json文件(當(dāng)然,有需要也可以上云通過配置后臺下發(fā)),對預(yù)請求的規(guī)則進行配置,并將這份配置在App啟動階段異步讀入到內(nèi)存。后續(xù)在路由過程中,只有命中了預(yù)請求規(guī)則,才能發(fā)起預(yù)請求。配置demo如下:

{
  "routeConfig":{
    "scheme://domain/path?param1=true&itemId=123":["prefetchKey"],
    "route2":["prefetchKey2"],
    "route3":["prefetchKey3","prefetchKey4"]
  },
  "prefetcher":{
    "prefetchKey":{
      "prefetchType":"network",
      "prefetchInfo":{
        "api":"network.api.name",
        "apiVersion":"1.0",
        "method":"post",
        "needLogin":"false",
        "showLoginUI":"false",
        "params": {
          "itemId":"$route.itemId",
          "firstTime":"true"
        },
        "headers": {
          
        },
        "prefetchImgInResponse": [
          {
            "imgUrl":"$data.imgData.img",
            "imgWidth":"$data.imgData.imgWidth",
            "imgHeight":150
          }
        ]
      }
    },
    "prefetchKey2":{
      "prefetchType":"network",
      "prefetchInfo":{
        "api":"network.api.name2",
        "apiVersion":"1.0",
        "method":"post",
        "needLogin":"false",
        "showLoginUI":"false",
        "params": {
          "itemId":"$route.productId",
          "firstTime":"false"
        },
        "headers": {
          
        }
    },
    "prefetchKey3":{
      "prefetchType":"image",
      "prefetchInfo":{
        "imgUrl":"$route.imgUrl",
        "imgWidth":"$route.imgWidth",
        "imgHeight": 150
      }
    },
    "prefetchKey4":{
      "prefetchInfo":{}
    }
  }
}

規(guī)則解讀

參數(shù)名描述備注
routeConfig路由配置配置路由到預(yù)請求的映射
prefetcher預(yù)請求配置記錄所有的預(yù)請求
prefetchKey預(yù)請求的key
prefetchType預(yù)請求類型分為network類型與image類型,兩種類型所需要的參數(shù)不同
prefetchInfo預(yù)請求所需要的信息其中value若為route.param格式,那么該值從路由中獲?。蝗魹閞oute.param格式,那么該值從路由中獲??;若為route.param格式,那么該值從路由中獲??;若為data.param格式,則從響應(yīng)數(shù)據(jù)中獲取。
paramsnetwork請求所需要的請求params
headersnetwork請求所需要的請求headers
prefetchImgFromResponse預(yù)請求的響應(yīng)返回后,需要預(yù)加載的圖片用于需要預(yù)加載圖片時,無法確定圖片url,圖片url只能從預(yù)請求響應(yīng)中獲取的場景。

舉例說明

網(wǎng)絡(luò)預(yù)請求

例如跳轉(zhuǎn)目標(biāo)頁面,它的路由是scheme://domain/path?param1=true&itemId=123。

首先我們在跳轉(zhuǎn)路由時,若跳轉(zhuǎn)的路由是這個目標(biāo)頁面,我們就會嘗試去發(fā)起預(yù)請求。根據(jù)上面的demo配置文件,它將匹配到prefetchKey這個預(yù)請求。

那么我們詳細看prefetchKey這個預(yù)請求,預(yù)請求類型prefetchTypenetwork,是一個網(wǎng)絡(luò)預(yù)請求,prefetchInfo中具備了請求的基本參數(shù)(如apiName、apiVersion、method、請求params與請求headers,不同工程不一樣,大家可以根據(jù)自己的工程項目進行修改)。具體看params中,有一個參數(shù)為itemId:$route.itemId。以$route.開頭的意思,就是這個value值要從路由中獲取,即itemId=123,那么這個值就是123。

圖片預(yù)請求

在做網(wǎng)絡(luò)預(yù)請求的過程中,我忽然想到圖片做預(yù)請求也是可以大大提升用戶體驗的,尤其是當(dāng)大圖片首次下載到內(nèi)存中渲染需要的時間會比較長。圖片預(yù)請求分為url已知url未知兩種場景,下面各舉兩個例子。

圖片url已知

什么是圖片url已知呢?比如我們在首頁跳轉(zhuǎn)首頁的二級頁面時,如果二級頁面需要預(yù)加載的圖片跟首頁的某張圖是一樣的(尺寸可能不同),那么首頁跳轉(zhuǎn)路由時我們是能夠提前知道這個圖片的url的,所以我們看到prefetchKey3中配置了prefetchTypeimage的預(yù)請求。image的信息來自于路由參數(shù),需要在跳轉(zhuǎn)時將圖片url和寬高作為路由參數(shù)之一。

比如scheme://domain/path?imgUrl=${encodeUrl}&imgWidth=200,那么根據(jù)配置項,我們將提前將encodeUrl這個圖片以寬200,高150的尺寸,加載到內(nèi)存中去。當(dāng)目標(biāo)頁面用到這個圖片時,將能很快渲染出來。

圖片url未知

相反,當(dāng)跳轉(zhuǎn)目標(biāo)頁面時,目標(biāo)頁面所要加載的圖片url沒法取到,就對應(yīng)了圖片url未知的場景。

例如閃屏頁跳轉(zhuǎn)首頁時,如果需要預(yù)加載首頁頂部的圖片,此時閃屏頁是無法獲取到圖片的url的,因為這個圖片url是首頁接口返回的。這種情況下,我們只能依賴首頁的預(yù)請求進行。

在demo配置文件中,我們可以看到prefetchImgFromResponse字段。這個字段代表著,當(dāng)這個預(yù)請求響應(yīng)回來之后,我需要去預(yù)請求某張圖片。其中,imgUrl$data.param格式,以$data.開頭,代表著這份數(shù)據(jù)是來自于響應(yīng)數(shù)據(jù)的。響應(yīng)數(shù)據(jù)就是一串json串,可以憑此,索引到預(yù)請求響應(yīng)中圖片url的位置,就能實現(xiàn)圖片的提前加載了。

至于圖片怎么提前加載到內(nèi)存中,以及真實圖片的加載怎么匹配到內(nèi)存中的圖片,這一部分是通過glide已有的preload機制實現(xiàn)的,感興趣的同學(xué)可以去看一下源碼了解一下,這里就不展開了。后面講的預(yù)請求的方案細節(jié),都只限于網(wǎng)絡(luò)請求。

預(yù)請求匹配

預(yù)請求匹配指的是實際的業(yè)務(wù)請求怎樣與已經(jīng)執(zhí)行的預(yù)請求匹配上,從而節(jié)省請求的空中時間,直接返回預(yù)請求的結(jié)果。

首先網(wǎng)絡(luò)預(yù)請求執(zhí)行前先在內(nèi)存中生成一份PrefetchRecord,代表著已經(jīng)執(zhí)行的預(yù)請求,其中的字段跟配置文件中差不多,主要就是記錄預(yù)請求相關(guān)的信息:

class PrefetchRecord {
    // 請求信息
    String api;
    String apiVersion;
    String method;
    String needLogin;
    String showLoginUI;
    JSONObject params;
    JSONObject headers;

    // 預(yù)請求狀態(tài)
    int status;
    // 預(yù)請求結(jié)果
    ResponseModel response;
    // 生成的請求id
    String requestId;

    boolean isMatch(RealRequest realRequest) {
        requestId.equals(realRequest.requestId)
    }
}

每一個PrefetchRecord生成時,都會生成一個requestId,用于跟實際業(yè)務(wù)請求進行匹配。requestId的生成規(guī)則可以自行制定,比如將所有請求信息包一起做一下md5處理之類。

在實際業(yè)務(wù)請求發(fā)起之前,也會根據(jù)同樣的規(guī)則生成requestId。若內(nèi)存中存在相同requestId對應(yīng)的PrefetchRecord,那么就相當(dāng)于匹配成功了。匹配成功后,再根據(jù)預(yù)請求的狀態(tài)進行進一步的處理。

預(yù)請求狀態(tài)

預(yù)請求狀態(tài)分為START、FINISH、ABORT,對應(yīng)“正在發(fā)起預(yù)請求”、“已經(jīng)獲得預(yù)請求結(jié)果”、“預(yù)請求被拋棄”。ABORT狀態(tài)下一節(jié)再講。

為什么要記錄這個狀態(tài)呢?因為我們無法保證,預(yù)請求的響應(yīng)一定在實際請求之前。用圖來表示:

因為預(yù)請求是一個并發(fā)行為。當(dāng)預(yù)請求的空中時間特別長,長到目標(biāo)頁面已經(jīng)發(fā)出實際請求了,預(yù)請求的響應(yīng)還沒回來,即預(yù)請求狀態(tài)為START,而非FINISH。那么此時該怎么辦?我們就需要讓實際請求在一旁等著(記錄到內(nèi)存中,RealRequestRecord),等預(yù)請求接收到響應(yīng)了,再根據(jù)requestId去進行匹配,匹配到RealRequestRecord了,就觸發(fā)RealRequestRecord中的回調(diào),返回數(shù)據(jù)。

另外,在匹配過程中需要注意一點,因為每次路由跳轉(zhuǎn),如果發(fā)起預(yù)請求了,總會生成一個Record在內(nèi)存中等待匹配。因此在匹配結(jié)束后,不管是匹配成功還是匹配失敗,都要及時釋放將Record從內(nèi)存中釋放掉。

超時重試機制

基于實際請求等待預(yù)請求響應(yīng)的場景,我們再延伸一下。若預(yù)請求請求超時,遲遲拿不到響應(yīng),該怎么辦?用圖表示:

假設(shè)目前的網(wǎng)絡(luò)請求,端上默認的超時時間是30s。那么在超時場景下,實際的業(yè)務(wù)請求在30s內(nèi)若拿不到預(yù)請求的結(jié)果,就需要重新發(fā)起業(yè)務(wù)請求,拋棄預(yù)請求,并將預(yù)請求的狀態(tài)置為ABORT,這樣即使后面預(yù)請求響應(yīng)回來了也不做任何處理。

忽然想到一個很貼切的場景來比喻這個預(yù)請求方案。

我們把跳轉(zhuǎn)頁面理解為去柜臺取餐。

預(yù)請求代表著我們?nèi)诉€沒到柜臺,就先遠程下單讓柜員去準(zhǔn)備食物。

如果柜員準(zhǔn)備得比較快,那么我們到柜臺后就能直接把食物拿走了,就能快點吃上了(代表著頁面渲染速度變快)。

如果柜員準(zhǔn)備得比較慢,那么我們到柜臺后還是得等一會兒才能取餐,但總體上吃上食物的速度還是要比到柜臺后再點餐來得快。

但如果這個柜員消極怠工準(zhǔn)備得太慢了,我們到柜臺等了很久都沒拿到食物,那么我們就只能換個柜員重新點了(超時后發(fā)起實際的業(yè)務(wù)請求),同時還不忘投訴一把(預(yù)請求空中時間太慢了)。

總結(jié)

通過這篇文章,我們知道了什么是接口預(yù)請求,怎么實現(xiàn)接口預(yù)請求。我們通過配置文件+統(tǒng)一路由處理+預(yù)請求發(fā)起、匹配、回調(diào),實現(xiàn)了與業(yè)務(wù)解耦的,可適用于任意頁面的輕量級預(yù)請求方案,從而提升頁面的渲染速度。

以上就是Android斬首行動接口預(yù)請求的詳細內(nèi)容,更多關(guān)于Android接口預(yù)請求的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android消息循環(huán)機制源碼深入理解

    Android消息循環(huán)機制源碼深入理解

    這篇文章主要介紹了Android消息循環(huán)機制源碼深入理解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • Android仿微信右上角點擊加號彈出PopupWindow

    Android仿微信右上角點擊加號彈出PopupWindow

    這篇文章主要為大家詳細介紹了Android仿微信右上角點擊加號彈出PopupWindow,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Android仿微信朋友圈圖片選擇器

    Android仿微信朋友圈圖片選擇器

    這篇文章主要為大家詳細介紹了Android仿微信朋友圈附加圖片功能,朋友圈圖片選擇器,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Flutter實現(xiàn)局部刷新

    Flutter實現(xiàn)局部刷新

    這篇文章主要為大家詳細介紹了Flutter實現(xiàn)局部刷新,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Android?IntentFilter的匹配規(guī)則示例詳解

    Android?IntentFilter的匹配規(guī)則示例詳解

    這篇文章主要為大家介紹了Android?IntentFilter的匹配規(guī)則示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Android Bitmap詳解及Bitmap的內(nèi)存優(yōu)化

    Android Bitmap詳解及Bitmap的內(nèi)存優(yōu)化

    這篇文章主要介紹了Android Bitmap詳解及Bitmap的內(nèi)存優(yōu)化的相關(guān)資料,Bitmap是Android系統(tǒng)中的圖像處理的最重要類之一。用它可以獲取圖像文件信息,進行圖像剪切、旋轉(zhuǎn)、縮放等操作,并可以指定格式保存圖像文件,需要的朋友可以參考下
    2017-03-03
  • Android中Service和Activity相互通信示例代碼

    Android中Service和Activity相互通信示例代碼

    在android中Activity負責(zé)前臺界面展示,service負責(zé)后臺的需要長期運行的任務(wù)。下面這篇文章主要給大家介紹了關(guān)于Android中Service和Activity相互通信的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-09-09
  • mac開發(fā)android環(huán)境搭建步驟圖解

    mac開發(fā)android環(huán)境搭建步驟圖解

    這里比較詳細的來總結(jié)下mac開發(fā)android的環(huán)境搭建步驟安裝過程,希望對一些正準(zhǔn)備配置Android開發(fā)環(huán)境的小伙伴們有一定幫助
    2014-01-01
  • Android 快速搭建FTP服務(wù)器的方法

    Android 快速搭建FTP服務(wù)器的方法

    這篇文章主要介紹了Android如何搭建FTP服務(wù)器,需要的朋友可以參考下
    2017-08-08
  • android開發(fā)實現(xiàn)列表控件滾動位置精確保存和恢復(fù)的方法(推薦)

    android開發(fā)實現(xiàn)列表控件滾動位置精確保存和恢復(fù)的方法(推薦)

    下面小編就為大家?guī)硪黄猘ndroid開發(fā)實現(xiàn)列表控件滾動位置精確保存和恢復(fù)的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03

最新評論