標籤:cto 大小 als cycle exit row utils prot ide
Bitmap的載入與緩衝程式碼分析:
圖片的壓縮
比如有一張1024*768像素的映像要被載入記憶體,然而最終你要用到的圖片大小其實只有128*96,那麼我們會浪費很大一部分記憶體,這顯然是沒有必要的,下面是一個執行個體:
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
為了使用以上的方法,我們在裁剪之前,一定要記得使用inJustDecodeBounder來擷取原圖大小,在使用完之後,記得將inJustDecodeBounds置為false:
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
在剪裁工作做完後,我們就可以將位元影像載入ImageView了,比如我們設定期望大小為100*100:
mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
記憶體緩衝技術
另外一種圖片緩衝的方式就是記憶體緩衝技術。在Android中,有一個叫做LruCache類專門用來做圖片緩衝處理的。
它有一個特點,當緩衝的圖片達到了預先設定的值的時候,那麼近期使用次數最少的圖片就會被回收掉。
步驟:(1)要先設定緩衝圖片的記憶體大小,我這裡設定為手機記憶體的1/8,
手機記憶體的擷取方式:int MAXMEMONRY = (int) (Runtime.getRuntime() .maxMemory() / 1024);
(2)LruCache裡面的索引值對分別是URL和對應的圖片
(3)重寫了一個叫做sizeOf的方法,返回的是圖片數量。
private LruCache<String, Bitmap> mMemoryCache;
private LruCacheUtils() {
if (mMemoryCache == null)
mMemoryCache = new LruCache<String, Bitmap>(
MAXMEMONRY / 8) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// 重寫此方法來衡量每張圖片的大小,預設返回圖片數量。
return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
}
@Override
protected void entryRemoved(boolean evicted, String key,
Bitmap oldValue, Bitmap newValue) {
Log.v("tag", "hard cache is full , push to soft cache");
}
};
}
(4)下面的方法分別是清空緩衝、添加圖片到緩衝、從緩衝中取得圖片、從緩衝中移除。
移除和清除緩衝是必須要做的事,因為圖片緩衝處理不當就會報記憶體溢出,所以一定要引起注意。
public void clearCache() {
if (mMemoryCache != null) {
if (mMemoryCache.size() > 0) {
Log.d("CacheUtils",
"mMemoryCache.size() " + mMemoryCache.size());
mMemoryCache.evictAll();
Log.d("CacheUtils", "mMemoryCache.size()" + mMemoryCache.size());
}
mMemoryCache = null;
}
}
public synchronized void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (mMemoryCache.get(key) == null) {
if (key != null && bitmap != null)
mMemoryCache.put(key, bitmap);
} else
Log.w(TAG, "the res is aready exits");
}
public synchronized Bitmap getBitmapFromMemCache(String key) {
Bitmap bm = mMemoryCache.get(key);
if (key != null) {
return bm;
}
return null;
}
/**
* 移除緩衝
*
* @param key
*/
public synchronized void removeImageCache(String key) {
if (key != null) {
if (mMemoryCache != null) {
Bitmap bm = mMemoryCache.remove(key);
if (bm != null)
bm.recycle();
}
}
}
Android藝術——Bitmap高效載入和緩衝程式碼分析(2)