提兵百万西湖上,立马吴山第一峰!这篇文章主要讲述Android艺术——Bitmap高效加载和缓存代码分析相关的知识,希望能为你提供帮助。
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;
}
【Android艺术——Bitmap高效加载和缓存代码分析】/**
* 移除缓存
*
* @param key
*/
public synchronized void removeImageCache(String key) {
if (key != null) {
if (mMemoryCache != null) {
Bitmap bm = mMemoryCache.remove(key);
if (bm != null)
bm.recycle();
}
}
}
推荐阅读
- Android4.0.4-在build.prop中添加属性的方法
- Android艺术——性能优化问题
- Common Words Used in Android
- SQL注入-攻入Apple ID钓鱼网站实录
- Appium在windows下的使用
- Android开发笔记(13)——ListFragment
- 利用浏览器调试APP中的H5页面
- Android艺术——Bitmap高效加载和缓存
- linux配置Android Studio的快捷启动方式