簡述
????最近任務(wù)卡片上的圖片資源主要有應(yīng)用圖標(biāo)和縮略圖冕房。應(yīng)用圖標(biāo)一般是固定的候址,加載后就放在緩存里,不需要每次從系統(tǒng)里加載∶勘遥縮略圖則有可能會經(jīng)常變化,所以經(jīng)常需要實時加載掩缓,加載的時候一般使用異步加載揽浙。
????圖標(biāo)和縮略圖從加載到顯示在卡片上的流程可以分為三部分。
????????1. 從系統(tǒng)預(yù)加載資源
????????2. 界面繪圖
????????3. 線程異步加載資源湾盗,加載后更新到界面
????????4. Android緩存策略——LruCache
1. 從系統(tǒng)預(yù)加載資源
最近任務(wù)模塊啟動后伏蚊,會在兩個回調(diào)函數(shù)中從系統(tǒng)預(yù)加載資源。分別是
????????RecentsImpl.onBootComplete
????????android.app.TaskStackListener mTaskStackListener.onTaskStackChanged
onBootComplete函數(shù)是在系統(tǒng)啟動完成后被調(diào)用的格粪,onTaskStackChanged是在ActivityManager發(fā)現(xiàn)系統(tǒng)的TaskStack發(fā)生變化以后調(diào)用的躏吊。
這兩個函數(shù)調(diào)用RecentsTaskLoader.loadTasks函數(shù)以同步的方式從系統(tǒng)加載資源。
loadTasks最終會調(diào)用兩個函數(shù)分別加載圖標(biāo)和縮略圖帐萎。
加載圖標(biāo)的函數(shù)是:RecentsTaskLoader.getAndUpdateActivityIcon
加載縮略圖的函數(shù)是:RecentsTaskLoader.getAndUpdateThumbnail
這兩個函數(shù)首先從緩存中查找圖標(biāo)比伏,如果緩存中有,并且沒有失效疆导,則使用緩存中的圖標(biāo)赁项,否則從系統(tǒng)中獲取。
圖標(biāo)緩存類是TaskKeyLruCache,縮略圖緩存類是TaskKeyStrongCache悠菜,這兩個類都是TaskKeyCache的子類紫新。TaskKeyCache通過比較Task.TaskKey.lastActiveTime來確定緩存是否失效
final V getAndInvalidateIfModified(Task.TaskKey key) {
Task.TaskKey lastKey = mKeys.get(key.id);
if (lastKey != null) {
if ((lastKey.stackId != key.stackId) ||
(lastKey.lastActiveTime != key.lastActiveTime)) {
// The task has updated (been made active since the last time it was put into the
// LRU cache) or the stack id for the task has changed, invalidate that cache item
remove(key);
return null;
}
}
// Either the task does not exist in the cache, or the last active time is the same as
// the key specified, so return what is in the cache
return getCacheEntry(key.id);
}
系統(tǒng)剛啟動完成的時候,緩存里是沒有資源的李剖,所以這個時候一般都是從系統(tǒng)加載資源芒率。
2. 界面繪圖
第一步從系統(tǒng)加載資源后,界面繪圖就要開始使用這些資源了篙顺。
使用資源是通過異步方式進行的偶芍。
TaskStackView.onMeasure
TaskStackView.bindVisibleTaskViews
ViewPool.pickUpViewFromPool
TaskStackView.createView
TaskStackView.onPickUpViewFromPool
TaskStackView.updateTaskViewsList //更新mTaskViews
TaskStackView.bindTaskView // 綁定taskView和應(yīng)用圖標(biāo)以及縮略圖
RecentsTaskLoader.loadTaskData // 把Task加入到mLoadQueue中,RecentsTaskLoader以異步方式加載應(yīng)用圖標(biāo)和縮略圖
在TaskStackView測量的時候德玫,會根據(jù)task列表創(chuàng)建TaskView匪蟀,為每個TaskView提交一個加載任務(wù)到RecentsTaskLoader。RecentsTaskLoader以異步的方式加載圖標(biāo)和縮略圖宰僧。
3. 線程異步加載資源材彪,加載后更新到界面
RecentsView被繪制之前,會啟動一個后臺線程mLoadThread琴儿,這個線程循環(huán)讀取mLoadQueue段化,為每一個task加載資源。
mRecentsDrawnEventListener //RecentsView視圖樹繪制前的回調(diào)接口
Recents.getTaskLoader().startLoader(RecentsActivity.this); //啟動RecentsTaskLoader的加載線程
BackgroundTaskLoader.start
mLoadThreadHandler.post(this) //投遞到HandlerThread線程造成, mLoadThreadHandler是HandlerThread的handler
RecentsTaskLoader.processLoadQueueItem
取cachedIcon
mIconCache.get(t.key)
ssp.getBadgedTaskDescriptionIcon
ssp.getActivityInfo(t.key.getComponent(), t.key.userId)
ssp.getBadgedActivityIcon(info, t.key.userId)
mIconCache.put(t.key, cachedIcon)
thumbnailData
ssp.getTaskThumbnail
這個線程里加載圖標(biāo)是優(yōu)先使用緩存里的數(shù)據(jù)显熏,縮略圖則是從系統(tǒng)獲取。
4. Android緩存策略——LruCache
一般來說晒屎,緩存策略主要包含緩存的添加喘蟆、獲取和刪除這三類操作。如何添加和獲取緩存這個比較好理解鼓鲁,那么為什么還要刪除緩存呢蕴轨?這是因為不管是內(nèi)存緩存還是硬盤緩存,它們的緩存大小都是有限的骇吭。當(dāng)緩存滿了之后橙弱,再想其添加緩存,這個時候就需要刪除一些舊的緩存并添加新的緩存绵跷。
因此LRU(Least Recently Used)緩存算法便應(yīng)運而生膘螟,LRU是近期最少使用的算法,它的核心思想是當(dāng)緩存滿時碾局,會優(yōu)先淘汰那些近期最少使用的緩存對象荆残。采用LRU算法的緩存有兩種:LrhCache和DisLruCache,分別用于實現(xiàn)內(nèi)存緩存和硬盤緩存净当,其核心思想都是LRU緩存算法内斯。
引用:http://www.reibang.com/p/b49a111147ee 徹底解析Android緩存機制——LruCache