Android Bitmap的加載與緩存
Android系統(tǒng)中圖片一般用Bitmap對象表示,它支持png,jpg等常見格式。通常情況下圖片的體積都比較大,單個應(yīng)用允許使用的內(nèi)存又是有限的,所以我們需要采取一些手段減少內(nèi)存占用并提高加載速度。
1、圖片加載
SDK提供了BitmapFactory類供我們加載圖片,常用的方法有這么幾個:
- BitmapFactory.decodeFile :從文件加載。
- BitmapFactory.decodeByteArray :從字節(jié)數(shù)組加載。
- BitmapFactory.decodeStream :從輸入流加載。
- BitmapFactory.decodeResource :從資源文件加載。
假設(shè)我們用ImageView顯示圖片,通常它的尺寸要比圖片的尺寸小很多,那么把圖片整個加載進(jìn)內(nèi)存顯然是沒有必要的。在圖形學(xué)上有個名詞叫“下采樣”,作用就是降低圖像的分辨率,使其符合顯示區(qū)域的大小。通過BitmapFactory.Options類,我們也可以實(shí)現(xiàn)同樣的功能。這里主要用到了它的 inSampleSize 參數(shù),如果它的值是1,那么采樣后的圖片跟原圖一致,如果是2,那么采樣后的圖片長和寬都是原來的一半,占用的內(nèi)存也就是原來的四分之一。
public static Bitmap decodeSampleBitmapFromBytes(byte[] data) { final BitmapFactory.Options options = new BitmapFactory.Options(); // inJustDecodeBounds為true時僅解析圖片原始信息,并不會真正加載圖片。 options.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(data, 0, data.length, options); // 此時圖片的寬高可以通過options.outWidth和options.outHeight獲取到,我們 // 可以根據(jù)自己的需求計算出采樣比。 options.inSampleSize = 1; // inJustDecodeBounds設(shè)置為fales,加載圖片到內(nèi)存中。 options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); }
2、圖片緩存
緩存在計算機(jī)領(lǐng)域使用非常廣泛,如HTTP緩存,DNS緩存等等,緩存既可以提高響應(yīng)速度,又能節(jié)省服務(wù)器帶寬,在圖片加載上它同樣適用。Android開發(fā)中一般會對圖片做兩級緩存:內(nèi)存緩存和文件緩存,而且它們都有庫供我們使用,分別是LruCache和DiskLruCache。從名字就可以看出兩者都使用了LRU算法,即優(yōu)先淘汰那些近期最少使用的緩存。
2.1、LruCache
LruCache是Android提供的一個緩存類,一般用來管理內(nèi)存緩存。
// #1:確定緩存大小。 int maxMemory = (int)(Runtime.getRuntime().totalMemory() / 1024); int cacheSize = maxMemory / 8; // #2:重寫sizeOf方法計算每個緩存對象的內(nèi)存占用。 LruCache<String, Bitmap> mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount(); } };
LruCache是一個泛型類可以容納各種對象,因而它無法計算被儲存對象的大小,所以我們需要重寫它的 sizeOf 方法,手動進(jìn)行計算。那LruCache是如何實(shí)現(xiàn)的呢,實(shí)際上它僅僅是對LinkedHashMap進(jìn)行了封裝并處理了線程安全問題。LinkedHashMap的構(gòu)造函數(shù)中有一個布爾類型的參數(shù), accessOrder ,當(dāng)它為 true 時元素按訪問順序存儲,為 false 時按插入順序存儲。當(dāng)元素按訪問順序存儲時在其尾部取出的元素也就是最近最少使用的元素,也就實(shí)現(xiàn)了LRU算法。LruCache只需要每次 put 函數(shù)被調(diào)用后計算當(dāng)前總緩存的大小,當(dāng)其超出門限值時移除位于LinkedHashMap尾部的元素即可。
2.2、DiskLruCache
DiskLruCache同LruCache一樣都使用LinkedHashMap實(shí)現(xiàn)LRU算法,但DiskLruCache在實(shí)現(xiàn)和使用上更復(fù)雜一些,畢竟需要對文件進(jìn)行管理。
獲得DiskLruCache對象需要調(diào)用 DiskLruCache.open 函數(shù):
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
它接收4個參數(shù),第一個是緩存區(qū)目錄,第二個是客戶端版本號,DiskLruCache認(rèn)為當(dāng)版本號發(fā)生變化時緩存是無效的,第三個參數(shù)代表每個鍵可以關(guān)聯(lián)幾個文件,最后一個參數(shù)指定的緩存區(qū)的大小。在創(chuàng)建對象時,DiskLruCache會根據(jù)緩沖區(qū)目錄下名為“journal”的日志文件在LinkedHashMap中為緩存文件建立索引,所有對緩沖區(qū)的操作都會被記錄在這個文件中。當(dāng)緩沖區(qū)大小到達(dá)門限值后根據(jù)LRU算法對文件進(jìn)行清理。
讀取緩存時使用 DiskLruCache.get 函數(shù):
public synchronized Snapshot get(String key) throws IOException
函數(shù)返回一個Snapshot對象,通過該對象我們可以獲取到緩存文件的輸入流,多個線程可以同時使用各自的SnapShot對象讀取同一個Key對應(yīng)的緩存。
操作緩存時使用 DiskLruCache.edit 函數(shù):
public Editor edit(String key) throws IOException
創(chuàng)建或更改完畢后用 Editor.commit 函數(shù)提交或用 Editor.abort 函數(shù)取消。一個Key對應(yīng)的緩存被操作時仍可以使用Snapshot對象讀取其內(nèi)容,因為Editor的所有操作都會先作用于臨時文件。注意每個Key只能同時獲取一個Editor對象,也就是說即使Editor沒有做任何操作也要調(diào)用 Editor.abort 或 Editor.commit 函數(shù),不然再次獲取時函數(shù)返回 null 。
2.3、代碼示例
public Bitmap loadBitmap(String url) { // DiskLruCache要求鍵中不能含有特殊字符,所以 // 一般先做哈希處理。 String key = MD5(url); Bitmap bitmap = loadBitmapFromMemCache(key); if (bitmap != null) { return bitmap; } try { bitmap = loadBitmapFromDiskCache(key); if (bitmap != null) { return bitmap; } bitmap = loadBitmapFromHttp(url); if (bitmap != null) { return bitmap; } } catch (IOException e) { e.printStackTrace(); } return null; }
在 loadBitmapFromHttp 函數(shù)中需要將圖片資源放入DiskLruCache中,在 loadBitmapFromDiskCache 函數(shù)中將加載后的Bitmap對象放入LruCache中,如此便形成了一條緩存鏈。
總結(jié)
以上所述是小編給大家介紹的Android Bitmap的加載與緩存,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- 詳解Android Bitmap的使用
- android獲取圖片尺寸的兩種方式及bitmap的縮放操作
- Android 實(shí)現(xiàn)把bitmap圖片的某一部分的顏色改成其他顏色
- Android 實(shí)現(xiàn)將Bitmap 保存到本地
- Android中的Bitmap序列化失敗的解決方法
- Android BitmapUtils工具類使用詳解
- 詳解Android Bitmap的常用壓縮方式
- Android中的Bitmap的詳細(xì)介紹
- Android圖片處理工具類BitmapUtils
- Android開發(fā)中Bitmap高效加載使用詳解
- Android中Glide獲取圖片Path、Bitmap用法詳解
- Android Bitmap像素級操作詳解
相關(guān)文章
初識Android?PowerManagerService省電模式
這篇文章主要介紹了初識Android?PowerManagerService省電模式,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-08-08Android中Fab(FloatingActionButton)實(shí)現(xiàn)上下滑動的漸變效果
這篇文章主要給大家介紹了Android中FloatingActionButton(簡稱FAB)是如何實(shí)現(xiàn)上下滑動的漸變效果,文中給出了詳細(xì)的示例代碼,相信對大家具有一定的參考價值,有需要的朋友們可以一起看看吧。2017-02-02android Matrix實(shí)現(xiàn)圖片隨意放大縮小或拖動
這篇文章主要為大家詳細(xì)介紹了android Matrix實(shí)現(xiàn)圖片隨意放大縮小或拖動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02Android 在viewPager中雙指縮放圖片雙擊縮放圖片單指拖拽圖片的實(shí)現(xiàn)思路
本文通過實(shí)例代碼給大家講解了Android 在viewPager中雙指縮放圖片雙擊縮放圖片單指拖拽圖片的實(shí)現(xiàn)思路及解決方案,需要的朋友參考下吧2017-05-05Android仿抖音右滑清屏左滑列表功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android仿抖音右滑清屏左滑列表功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06Android性能優(yōu)化之弱網(wǎng)優(yōu)化詳解
這篇文章主要為大家介紹了Android性能優(yōu)化之弱網(wǎng)優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10Android開發(fā)使用自定義View將圓角矩形繪制在Canvas上的方法
這篇文章主要介紹了Android開發(fā)使用自定義View將圓角矩形繪制在Canvas上的方法,結(jié)合實(shí)例形式分析了Android自定義view繪制圓角矩形的相關(guān)方法與使用技巧,需要的朋友可以參考下2017-10-10