整體架構
初始化的時候會加載整個XML到記憶體中
作為記憶體緩存
這也是不能跨程序的原因,任何東西隻要做緩存那就是2套資料了,即使SP做了多程序措施也無濟于事
- 取:從記憶體取
- commit:直接同步執行
- apply:入隊
引起ANR的原因
取是不會有ANR的,隻需要在最初加載檔案的時候讀取一次即可,後續都是從記憶體去取
commit直接在目前線程執行,雖說SP是輕量級的IO,但是至少也是IO操作,做個最簡單的IO操作,也要幾百ms
apply入隊本是對此很不錯的優化,但是最坑的一點是,Activity、Service、Broadcast都會在某些條件下等待SP隊列全部執行完成
Google美名其曰確定IO可以順利執行
可以參考Activity ANR的堆棧
waitToFinish方法會加鎖,等待queue清空
public static void waitToFinish() {
long startTime = System.currentTimeMillis();
boolean hadMessages = false;
Handler handler = getHandler();
synchronized (sLock) {
if (handler.hasMessages(QueuedWorkHandler.MSG_RUN)) {
// Delayed work will be processed at processPendingWork() below
handler.removeMessages(QueuedWorkHandler.MSG_RUN);
if (DEBUG) {
hadMessages = true;
Log.d(LOG_TAG, "waiting");
}
}
// We should not delay any work as this might delay the finishers
sCanDelay = false;
}
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
try {
processPendingWork();
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
try {
while (true) {
Runnable finisher;
synchronized (sLock) {
finisher = sFinishers.poll();
}
if (finisher == null) {
break;
}
finisher.run();
}
} finally {
sCanDelay = true;
}
synchronized (sLock) {
long waitTime = System.currentTimeMillis() - startTime;
if (waitTime > 0 || hadMessages) {
mWaitTimes.add(Long.valueOf(waitTime).intValue());
mNumWaits++;
if (DEBUG || mNumWaits % 1024 == 0 || waitTime > MAX_WAIT_TIME_MILLIS) {
mWaitTimes.log(LOG_TAG, "waited: ");
}
}
}
}
是以解決方式是反射清理等待鎖
磁盤緩存架構選型
目前頂級項目很少會采用SP來進行磁盤緩存了,其ANR是一個繞不開的坎
先不說apply引起的ANR
很多時候,很多業務場景,對業務即時性的要求很高,是以必須采用commit的形式去做緩存
這個時候就對緩存架構的IO速度有極高的要求了
顯然SP沒有那麼高效
微信開源的MMKV是值得使用的,雖然還有一些小坑會導緻異常的ANR,但是整體上來說,是最頂級的緩存架構
原理
上面的整體架構有介紹原理了
也是比較易于了解,通俗易懂的
是以源碼細節這裡不再過多糾結了
想學習一些并發、IO的細節可以參考 https://mp.weixin.qq.com/s/qXQQb0IxrYeAFmrvXLydmA?client=tim&ADUIN=136284008&ADSESSION=1555676164&ADTAG=CLIENT.QQ.5603_.0&ADPUBNO=26882
後記
有什麼寫得錯誤、讓人費解或遺漏的地方,希望可以不吝賜教,我會馬上更改
學習自
https://mp.weixin.qq.com/s/qXQQb0IxrYeAFmrvXLydmA?client=tim&ADUIN=136284008&ADSESSION=1555676164&ADTAG=CLIENT.QQ.5603_.0&ADPUBNO=26882
https://www.jianshu.com/p/9ae0f6842689