標籤:android des style color 使用 strong
載入流程:
if(記憶體命中){ 從記憶體中讀取}else{ create AsyncTasks,task中的多個Runnable是通過堆棧先進後出的方式來調度,而非隊列式的先進先出,目的是最先載入使用者最近划到或開啟的圖片。 } AsyncTask: //do in background——該後台進程在使用者scroll列表的時候會暫停,從而減小了列表划動時cpu的overhead,此方法也被ImageLoader和facebook的官方app所使用。if(磁碟快取命中){ 從緩衝中讀取 }else{ 從網路下載 成功後,存入磁碟緩衝並且存入記憶體}
記憶體配置圖片管理LruCache,容量為1/10運行時記憶體。以nexus 4為例,記憶體2G,jvm為樣本app分配的可用記憶體為512MB,那麼記憶體中的圖片LruCache大小為51.2MB。當達到容量後,不要直接recycle bitmap,而是將bitmap加到一個WeakReference的Map中;否則在小記憶體手機上,很可能會recycle掉一些還被引用著的bitmap。
緩衝圖片管理ChocolateCache,策略類似於LruCache,但是對IO讀寫速度和命中率都做了最佳化(鳴謝 伯奎)
下載和解析圖片的注意事項黑圖問題: // 如果不根據這個固定的length來產生byte[],而是直接decode // inputstream ,會造成黑圖(圖片出現黑色的矩形) imgData =
new
byte[length];
byte[] temp =
new
byte[512];
int readLen = 0;
int destPos = 0;
while ((readLen = mInputStream.read(temp)) > 0) { System.arraycopy(temp, 0, imgData, destPos, readLen); destPos += readLen; } 機型和網路相容性問題:三星note3在CDMA網路下得到的是GZIPInputStream(length為-1),其他機型和情境都是FixedLengthInputStream(length為正常大小),所以當length=-1時,採用最基本的InputStream->OutputStream->ByteArray的方式產生映像的位元組數組 不同解析度顯示時的自動縮放問題(尤其是表情模組)解析圖片應採用BitmapFactory.decodeStream而不是BitmapFactory.decodeByteArray,因為後者在從source density到target density轉換時,不會自動縮放。例如,某250x250的圖片,預設的density是320,但是LG的G2手機density為480,所以此圖片應按照480/320=1.5的比例放大並顯示到G2手機上。但是decodeByteArray之後得到的圖片長寬仍然是250x250,但是如果使用decodeStream則會得到長寬均為250*1.5=375的圖片,從而實現了最佳的顯示效果。 根本原因詳見源碼:
public
static Bitmap decodeStream (InputStream is, Rect outPadding, Options opts) { ... ...
if (opts ==
null || (opts. inScaled && opts. inBitmap ==
null)) {
float scale = 1.0f;
int targetDensity = 0;
if (opts !=
null) {
final
int density = opts. inDensity; targetDensity = opts. inTargetDensity;
if (density != 0 && targetDensity != 0) { scale = targetDensity / (
float) density;
//請注意這裡有計算縮放比例,而
decodeByteArray未進行此項操作
} } bm =
nativeDecodeAsset(asset, outPadding, opts,
true, scale);
if (bm !=
null && targetDensity != 0) bm.setDensity(targetDensity); finish =
false; }
else { bm =
nativeDecodeAsset(asset, outPadding, opts); } } ... ...
public
static Bitmap decodeByteArray (
byte [] data,
int offset,
int length, Options opts) {
if ((offset | length) < 0 || data. length < offset + length) {
throw
new ArrayIndexOutOfBoundsException(); } Bitmap bm =
nativeDecodeByteArray(data, offset, length, opts);
if (bm ==
null && opts !=
null && opts. inBitmap !=
null) {
throw
new IllegalArgumentException( "Problem decoding into existing bitmap"); }
return bm; }
情境策略網狀圖片按原尺寸處理本地圖片或拍照圖片,因為經常是高清大圖,所以需要根據具體情況設定採樣率,減小decode bitmap和write to cache時的記憶體佔用(鳴謝 風念)