首先我一般使用的適配器是BaseAdapter,其中有兩個方法最主要,分別是: getCount,getView,
在對Listview 進行優化的時候,首先使用 convertview 和viewHolder 配合進行優化,使用convertview的母的是
控件復用,從而加到減少內存的使用,使用viewHolder 的是減少findbyid 的次數.
但是在進行控件以后,在進行圖片加載的時候,會出現圖片錯位的問題,這是因為控件里面有上次殘留的圖片在里面,所以我們在初始化的時候需要設置一張默認圖,清楚上次殘留的圖片,從而避免圖片錯位.
注意: 在進行圖片加載的時候一般會造成 OOM(內存溢出),這個時候我們需要用到三級緩存策略,來進行處理,
首先三級緩存分別是:
1:強引用(Lrucache)
2:軟引用(SoftRenfence)
3:SD卡(現在被 DisKLrucache)
首先當我們需要加載圖片的時候:
首先從強引用里面找,如果強引用沒有,就從軟引用里面找,如果軟引用沒有就從SD卡里面找,如果SD卡沒有就從網絡加載,通過加載請求到的圖片存入到強引用(Lrucache)里面.
第二:強引用一般取內存的四分之一,當強引用滿了以后,就通過Lrucache 算法講部分圖片刪除,同時存入到軟引用里面,當軟引用滿了,就將部分圖片存入到SD卡里面,當SD卡滿了,就將一半的刪除,(刪除的時候根據使用日期排序),
注意:強引用是不能被垃圾回收機制回收的,軟引用是可以隨時被垃圾回收機制回收的.
:一半情況下我們加載的圖片的 url,是服務器經過二次采樣以后的url,只有當點擊看大圖的時候才加載原圖.
:無論在強引用,軟引用還是SD卡我們存圖片的時候都是以鍵值對的形式存的,他的鍵就是url,一般情況下使用MD5對URL進行加密,這樣做的目的是為了避免URL 里面有非法字符.
二次采樣:
注意:二次采樣分兩部進行,首先第一步我們需要獲取圖片的寬和高,同時獲取到需要采樣后的寬和高,通過寬和高計算出我們需要的采樣比,第二步:通過采樣比讓我們的圖片真正實現采樣縮放.
案例如下:
第一步:
假如說我有一張圖片是200*200,那么我想把這張圖片的縮略圖顯示在一個50*50的ImageView上,那我的壓縮比例應該為4,(這就是我們第一步的操作了,我先加載圖片的邊界到內存中,這個加載操作并不會耗費多少內存)
?
第二步:
在第一次采樣的基礎上,我來進行二次采樣。二次采樣的時候,我把第一次采樣后算出來的結果作為一個參數傳遞給第BitmapFactory,這樣在加載圖片的時候系統就不會將整張圖片加載進來了,而是只會加載該圖片的一張縮略圖進來,這樣不僅提高了加載速率,而且也極大的節省了內存,而且對于用戶來說,他也不會有視覺上的差異
?
具體代碼如何實現:
?
第一次采樣:首先獲取new BitmapFactory.Options()獲取option對象, inJustDecodeBounds
設置為true只會加載圖片的邊框進來,并不會加載圖片具體的像素點,通過BitmapFactory.decodeFile(filePath, options);來進行第一次加載圖片,通過outWidth原圖的寬度,通過outHeight獲取原圖的高,接下來通過控件的寬度和控件的高度來獲取一個采樣率sampleSize,接下來進行第二次采樣設置inJustDecodeBounds為false,同時設置縮放比,設置inPreferredConfig的圖片的圖片格式有(分別為ALPHA_8,RGB_565,ARGB_4444,ARGB_8888),最后進行圖片的加載.
?
具體實現代碼:
?
BitmapFactory.Options options = new BitmapFactory.Options();
// 第一次:設為true時,僅僅得到邊界,即寬高
options.inJustDecodeBounds=true;
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(),options);
?
// 第二次:將options的值設為Config.RGB_565,會比默認的Config.ARGB_8888減少一半內存;
options.inPreferredConfig= Bitmap.Config.RGB_565;
// 將邊框縮減到原來寬高的1/100;
options.inSampleSize=Math.max(options.outWidth,options.outHeight)/100;
// 設置為false,表示不僅僅加載邊框,
options.inJustDecodeBounds=false;
bitmap=BitmapFactory.decodeFile(file.getAbsolutePath(),options)