用乙個demo展示okhttp如何對介面資料進行快取;
講解okhttp資料快取的流程以及原理。
注意:okhttp只支援get
請求的快取,get
請求多用於查詢,資料更改沒那麼頻繁,而post
請求多使用者資料互動,而且每個快取檔名稱都是用介面的url進行md5加密後生成的,如果post請求的引數更改的話,就沒法考慮到,okhttp設計者就只支援get
方式了。如果還是想將post
請求資料快取到本地,只能自己另外設計快取策略了。``
設定介面資料快取可以有兩種方式,一種是新增***,另外一種是直接在request.builder
類中設定cachecontrol
:
//新增本地***
.addinterceptor
(new
localcacheinterceptor
(10000))
//設定快取位置,此屬性必須設定
;}設定快取***的好處就是,可以將快取部分,或者說快取策略剝離開來,達到低耦合的效果,自定義的快取***內容如下:
/**
* 此***為攔截本地快取,不會對快取資料造成影響,只會影響到是否能獲取到本地快取資料
*/public
class
localcacheinterceptor
implements
interceptor
@override
public response intercept
(chain chain)
throws ioexception
}catch
(exception e)
}//如果沒有網路,就走快取
cachecontrol =
newcachecontrol.builder()
.maxage
(integer.max_value, timeunit.seconds)
.maxstale
(integer.max_value, timeunit.seconds)
.build()
; request = builder.
cachecontrol
(cachecontrol)
.build()
;return chain.
proceed
(request);}
public
static
boolean
isnetworkconnected()
return
false;}
}
在上面的快取***中,我設定的是,當有網路時,去請求後台資料,沒網路時,走本地的快取資料,當然,這可以根據實際應用場景新增快取策略。比如,我設定一天內不管有沒有網路,都走快取資料等。具體的快取操作,是在cacheinterceptor
快取***裡設定的:
public response intercept
(chain chain)
throws ioexception ..
....
return response;
}
最後在自定義的快取資料夾中,檔案截圖如下:
檔名是以請求的url進行md5加密後的32位字串,字尾.0
的表示儲存的響應頭資料,字尾.1
的表示儲存的響應體body的資料,最後乙個檔案journal
,表示檔案快取的歷史記錄。
每一條快取對應兩個狀態副本:dirty,clean。clean表示當前可用的cache。dirty為編輯狀態的cache。由於更新和建立都只操作dirty狀態的副本,實現了讀和寫的分離。
每乙個url對應四個檔案,兩個狀態(diry,clean),每個狀態對應兩個檔案:0檔案對應儲存meta資料,1檔案儲存body資料。
maxage: 資料快取在本地的時間。
maxstale: 多長時間內可以使用快取資料。
cache
類本身是final
的,說明不能被繼承;所有的方法都是預設的,說明不能被外部呼叫。cache
類所有的方法呼叫,都是通過內部實現介面internalcache
來的:
final internalcache internalcache =
newinternalcache()
@override
public cacherequest put
(response response)
throws ioexception
@override
public
void
remove
(request request)
throws ioexception
@override
public
void
update
(response cached, response network)
@override
public
void
trackconditionalcachehit()
@override
public
void
trackresponse
(cachestrategy cachestrategy)
};
cache
類中對資料的增刪改查操作,其實主要是對disklrucache
類的操作,這個從cache
類的構造方法就可以看出:
final disklrucache cache;
public
cache
(file directory,
long maxsize)
cache
(file directory,
long maxsize, filesystem filesystem)
接下來,就是主要看okhttp
中關於快取的核心類-disklrucache
。
磁碟快取,通過linkedhashmap實現lru替換;
通過維護本地cache的操作日誌(journal
檔案),來保證cache
的可見性和原子性;
每乙個cache
對應兩個狀態:dirty
和clean
,dirty
是編輯狀態,更新和插入都是在這個狀態操作的;clean
是可用的狀態,查詢是在這個狀態下操作的,從而實現了讀寫分離;
每個url
請求對應4個檔案,兩個狀態(dirty
和clean
),字尾為.0
的表示響應頭資料,字尾為.1
的表示響應體body資料。
由於快取層對資料的讀寫操作比較多,也是用的okio包,這裡就簡單表述一下okio的讀寫資料的操作吧:
//將資料寫入檔案
void
write2file
(string response)
if(path != null && path.
exists()
)});
}catch
(ioexception e)
finally
catch
(ioexception e)}}
}//從檔案中讀取資料
void
readfromfile()
file file =
newfile
(path,
"b.txt");
if(file.
exists()
) tv.
settext
(sb);}
catch
(ioexception e)
}}
參考文章
okhttp3原始碼分析[disklrucache]
使用okio優化io
okio庫的使用
okhttp快取策略
okhttp原始碼解析(七)–中階之快取機制
Okhttp3原始碼分析之六
了解okhttp的都知道,它提供websocket的使用 宣告okhttp client 建立websocket request request new request.builder url serverurl build websocket client.newwebsocket request...
網路爬蟲之模擬登陸(二)安卓okhttp模擬登陸
之前那個部落格寫的有點錯誤,想想,還是不刪了,以後看到就當是個彎路的教訓okhttpclient client new okhttpclient 這個formbody就寫剛才的引數表裡的內容,鍵值對的形式,有幾條加幾個add 我這裡只是舉個例子,大概寫了兩個鍵值對,大家在寫的時候一定要寫全,有幾條寫...
安卓高階之效能優化全解析(一)
這篇文章作為android效能優化的引入,android的效能優化一直是廣大開發者頭疼的問題,也是非常重要的乙個知識點,這裡面涉及到的知識比較多,不知道大家對效能優化了解多少,首先問一下大家,你所知道的效能優化有多少種?如果是很少關注效能這塊的開發者或者初級程式設計師,可能會一臉懵逼,似曾相識卻又回...