編輯:關於Android編程
上節我們把妹子圖片的數據來源從本地改成了解析Gank提供的接口數據,我們本節想對這個圖片加載類進行優化,比如加上顯示本地圖片的,另外還有一點就是緩存,我們現在用得圖片加載沒有任何緩存可言,每次都是請求後,解析流,即使是同樣的圖片每次都要去請求一次,這顯得有點累贅,把圖片緩存到內存,或者磁盤裡,當訪問相同的圖片資源我們從這裡拿?嗯,好像很有搞頭,那麼本節我們就來寫一個簡單的帶緩存的圖片加載框架吧!嗯,就叫SisterLoader吧!
(PS:拖著好久沒更的原因是因為自己最近在看下載相關的東西,還有改BUG寫圖片加載的時候因為一些問題卡住了,抽不出時間解決…)<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxociAvPg0KPGgyIGlkPQ=="2簡單常識科普">2.簡單常識科普
開始寫代碼之前我們先來撸清楚一些概念先:
①引入圖片緩存的目的:
答:從網絡加載圖片費時費電費流量,我們希望把一些加載過的圖片可以存起來,
當再次加載時可以復用這個圖片。
②什麼是二級緩存:
答:說下需要顯示一張圖片所經歷的邏輯,你就一清二楚了:
需要顯示圖片 ——> 查內存(有的話顯示) —沒有—>查磁盤(有的話顯示) —沒有—>
從網絡加載(顯示出來) ——> 往內存中存一份 ——> 往磁盤存一份
從上我們知道,緩存有兩種,內存緩存和磁盤緩存(SD卡/機身存儲):
內存緩存:一級緩存,優先從這裡拿,緩存文件存儲在data/data/包名/cache目錄下,
以前寫內存緩存的老舊套路是用Map弱引用的Bitmap對象,我翻了翻上上上家公司的祖傳代碼:
public class MemoryCache { private static final int MAX_CACHE_COUNT = 30; //設置最大緩存數 /** Map弱引用Bitmap,內存夠的情況Bitmap不會被回收,當緩存數大於阈值,會清除最早放入緩存的 */ private HashMap> mCacheMap = new LinkedHashMap >() { @Override protected boolean removeEldestEntry(Entry eldest) { return size() > MAX_CACHE_COUNT; } }; /** * 添加圖片到緩存中 * */ public void put(String id,Bitmap bitmap) { mCacheMap.put(id, new SoftReference<>(bitmap)); } /** * 取出緩存中的圖片 * */ public Bitmap get(String id,Bitmap bitmap) { if(!mCacheMap.containsKey(id))return null; SoftReference ref = mCacheMap.get(id); return ref.get(); } /** * 清除所有緩存 * */ public void clear() { try{ for (Map.Entry >entry : mCacheMap.entrySet()) { SoftReference sr = entry.getValue(); if(null != sr) { Bitmap bitmap = sr.get(); if(null != bitmap) { bitmap.recycle(); } } } } catch (Exception e) { e.printStackTrace(); } } }
而Google老東家並不建議這樣做,官方最佳實踐中給我們推薦了關於緩存的兩個API:
LruCache(內存緩存) 和 DiskLruCache(磁盤緩存)
LruCache是以強引用(直接引用)的方式引用外界的緩存對象的,不會被GC回收,
而SoftReference引用,當系統內存不足的時候回隨GC回收
還有個WeakRefreence,隨時都可能會被系統回收…
如果你對這個很有興趣,可移步到官方的最佳實踐:Caching Bitmaps
磁盤緩存:
每個應用的內存都是有限的,如果是大批量的圖片,不可能全部塞到內存中,
我們可以考慮把圖片保存到磁盤中,老舊的做法是在SD上創建一個文件夾,
然後把圖片保存到裡面,網上很容易就能找到代碼,這裡不討論這個,本節
我們用上面Google推薦的DiskLruCache來做磁盤緩存
同步和異步的概念,相信很多人都了然於心了,簡單點說:
同步:發出加載圖片的調用後,要直到完成加載才能夠做其他操作
異步:發出加載圖片的調用後,想干嘛就干嘛,不用等他加載完才能去做其他事。
以前在入門教程那裡寫過就不再重復了:
Android基礎入門教程——8.2.1 Bitmap(位圖)詳解
Android基礎入門教程——8.2.2 Bitmap引起的OOM問題
也可以移步到我的好基友——基神的個人博客查看,解釋得更加詳細:
Android Bitmap 優化(1) - 圖片壓縮
Android Bitmap 優化(2) - 圖片緩存
盡管代碼不算復雜,覺得還是有必要畫個流程圖幫助大家理解一下~
PS:思前想後,還是把貼代碼還是放最後吧,只做下代碼折疊截圖簡單
解釋一波,具體自己看代碼,
這個是Google提供的,直接下這個類
https://android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/DiskLruCache.java
然後加到你的工程裡,自己改下包名就能用了~
PS: 設置ImageView大小用到
PS:就是異步加載圖片後傳給Handler的數據集合
private SisterLoader mLoader; mLoader = SisterLoader.getInstance(MainActivity.this); mLoader.bindBitmap(data.get(curPos).getUrl(),showImg,400,400);
被人趕出辦公室了,效果圖其實和前面的效果是一樣的,不過加入了我們的
圖片加載框架,加載過的圖片會緩存起來,下次加載同樣的圖片就能
很快顯示,具體效果還可以看打印的Log~(明天補下圖)
本節代碼是切換到新的分支下編寫的:sisterloader
代碼編寫完後,本地直接merge到develop分支,最後推送到Github的!
命令和上節的一樣!
https://github.com/coder-pig/DrySister/tree/develop
Android的animation由四種類型組成Android動畫模式Animation主要有兩種動畫模式:一種是tweened animation(漸變動畫) XM
在Android實現沒有標題欄的方法有兩種:在代碼中添加requestWindowFeature(Window.FEATURE_NO_TITLE); 在清單文件Andro
(一)概述好的,我們在前三節中對Android中的Activity進行了研究學習,相信大家獲益良多吧! 本節開始我們繼續來學習Android中的第二個組件:Service
我們要實現的目標是:做一個短信發送器 界面: 因為要涉及到短信發送這種屬於隱私的問題,所以我們要在AndroidManifest.xml中添加一行代碼,來獲得權限: 然