經常使用的內存緩存是軟引用和弱引用,大部分的使用方式是Android提供的LRUCache緩存策略,本質是個LinkedHashMap(會根據使用次數進行排序)java
DiskLruCache:非谷歌官方編寫,可是得到官方認證android
getCacheDir()是獲取app在手機內部存儲的cache目錄
getFilesDir()是獲取app在手機內部存儲的files目錄算法
經過Context.getExternalFilesDir()能夠獲取到app在sdcard上的files目錄,一般用於存放要長時間保存的數據
經過Context.getExternalCacheDir()能夠獲取到app在sdcard上的cache目錄,一般用於存放一些臨時數據
使用上面兩個api,在app被卸載的時候,在sdcard上對應的全部文件也會自動被刪除,不會留下垃圾信息
並且上面兩個目錄在設置裏的應用詳情裏,可使用清除數據和清除緩存來清理臨時文件api
LRU(Least Recently Used)緩存算法,近期最少使用的算法
LruCache是Android 3.1之後提供的一個緩存類數組
LruCache的緩存大小通常爲當前進程可用容量的1/8
重寫sizeOf方法,計算每一個緩存對象的大小
注意:緩存的總容量和每一個緩存對象的大小所用的單位要一致緩存
在構造函數中,可使用accessOrder參數來控制雙向鏈表的結構是訪問順序仍是插入順序
其中accessOrder設置爲true則爲訪問順序,爲false,則爲插入順序。
設置LinkedHashMap的accessOrder爲true,並向裏面插入數據後隨機訪問數據,將訪問數據後的LinkedHashMap輸出,最近訪問數據的最後輸出網絡
LruCache內部使用LinkedHashMap的訪問順序特性,來緩存數據
當調用put()方法時,就會在集合中添加元素,並調用trimToSize()來判斷緩存是否已滿,若是滿了就刪除隊尾元素
當調用get()方法時,就會調用LinkedHashMap的get()方法得到對應的元素,同時會更新該元素到隊首數據結構
DiskLruCache目前還不是Android SDK的一部分,可是Android官方文檔推薦使用該算法來實現磁盤緩存app
DiskLruCache不能new出實例,須要調用它的open()方法
open()方法接收四個參數:函數
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
- directory:數據的緩存地址
- appVersion:當前應用程序的版本號
- valueCount:同一個key能夠對應多少個緩存文件,基本都是傳1
- maxSize:最多能夠緩存多少字節的數據
public File getDiskCacheDir(Context context, String uniqueName) { String cachePath; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { cachePath = context.getExternalCacheDir().getPath(); } else { cachePath = context.getCacheDir().getPath(); } return new File(cachePath + File.separator + uniqueName); }
能夠看到,當SD卡存在或者SD卡不可被移除的時候,就調用getExternalCacheDir()方法來獲取緩存路徑,不然就調用getCacheDir()方法來獲取緩存路徑。前者獲取到的就是 /sdcard/Android/data/
接着是應用程序版本號,咱們可使用以下代碼簡單地獲取到當前應用程序的版本號:
public int getAppVersion(Context context) { try { PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); return info.versionCode; } catch (NameNotFoundException e) { e.printStackTrace(); } return 1; }
DiskLruCache mDiskLruCache = null; try { File cacheDir = getDiskCacheDir(context, "bitmap"); if (!cacheDir.exists()) { cacheDir.mkdirs(); } mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024); } catch (IOException e) { e.printStackTrace(); }
插入使用DiskLruCache.Editor這個類來完成,一樣,它也不能new出實例,須要使用edit()方法
public Editor edit(String key) throws IOException
// get()方法要求傳入一個key來獲取到相應的緩存數據,而這個key毫無疑問就是將圖片URL進行MD5編碼後的值了 public synchronized Snapshot get(String key) throws IOException
public synchronized boolean remove(String key) throws IOException
參考文檔:
http://blog.csdn.net/guolin_blog/article/details/28863651
http://blog.csdn.net/guolin_blog/article/details/34093441