您的位置:首页 > 其它

Bitmap的加载和Cache

2016-06-12 16:58 204 查看
一、Bitmap的高效加载

1、Bitmap的加载方式

1)、decodeFile

2)、decodeResource

3)、decodeStream

4)、decodeByteArray

2、BitmapFactory.Options缩放图片:采样率inSampleSize

1)、采样率取值:取值为2的指数,如果不是,则自动向下取整选择最接近的2的指数代替。

2)、采样率选择:缩放后的大小应大于ImageView大小,否则会由于拉伸导致模糊

3)、加载图片:

a、BitmapFactory.Options的inJustDecodeBounds设置为true并加载图片

b、从BitmapFactory.Options的outWidth和outHeight参数取出图片原始宽高

c、计算采样率

d、BitmapFactory.Options的inJustDecodeBounds设置为false并重新加载图片

二、Android中的缓存策略

1、缓存:

1)、概念:程序第一次从网络加载图片后,将其缓存到存储设备上,下次使用就不再从网络上获取了。为提高用户体验,还会在内存中缓存一份,这样请求图片时,首先去内存获取,没有则从存储设备获取,再没有则从网络加载。

2)、缓存策略:缓存的添加、获取和删除。常用算法:LRU

3)、LruCache

a、创建

<span style="white-space:pre">		</span>int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// TODO Auto-generated method stub
return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
}
};


b、获取、添加、删除一个缓存对象

<span style="white-space:pre">		</span>mMemoryCache.get(key);
mMemoryCache.put(key, value);
mMemoryCache.remove(key);

4)、DiskLruCache

a、创建

<span style="white-space:pre"> </span>File diskCacheDir = getDiskCacheDir(mContext, "bitmap");//获取缓存文件夹的方法
if (!diskCacheDir.exists()) {
diskCacheDir.mkdirs();
}
if (getUsableSpace(diskCacheDir) > DISK_CACHE_SIZE) {
try {
mDiskLruCache = DiskLruCache.open(diskCacheDir, 1, 1,
DISK_CACHE_SIZE);
mIsDiskLruCacheCreated = true;
} catch (IOException e) {
e.printStackTrace();
}
}b、添加
// 使用MD5算法获取字符串的Hash值//
private String hashKeyFormUrl(String url) {
String cacheKey;
try {
final MessageDigest mDigest = MessageDigest.getInstance("MD5");
mDigest.update(url.getBytes());
cacheKey = bytesToHexString(mDigest.digest());
} catch (NoSuchAlgorithmException e) {
cacheKey = String.valueOf(url.hashCode());
}
return cacheKey;
}
//将MD5字节数组转换成字符串
private String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1) {
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
}
<span style="white-space:pre">		</span>//获取editor创建输出流,通过输出流将文件写入文件系统
String key = hashKeyFormUrl(url);
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor
.newOutputStream(DISK_CACHE_INDEX);
if (downloadUrlToStream(url, outputStream)) {
editor.commit();
} else {
editor.abort();
}
mDiskLruCache.flush();
}
/**
* 将文件输出流写入文件系统
*
* @param urlString
*            图片地址
* @param outputStream
*            输出流
* @return 写入结果状态
*/
public boolean downloadUrlToStream(String urlString,
OutputStream outputStream) {
HttpURLConnection urlConnection = null;
BufferedOutputStream out = null;
BufferedInputStream in = null;

try {
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(),
IO_BUFFER_SIZE);
out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);

int b;
while ((b = in.read()) != -1) {
out.write(b);
}
return true;
} catch (IOException e) {
Log.e(TAG, "downloadBitmap failed." + e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
MyUtils.close(out);//关闭流的方法
MyUtils.close(in);
}
return false;
}
c、查找
<span style="white-space:pre"> </span>//查找缓存
Bitmap bitmap = null;
String key = hashKeyFormUrl(url);
DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
if (snapShot != null) {
FileInputStream fileInputStream = (FileInputStream) snapShot
.getInputStream(DISK_CACHE_INDEX);
FileDescriptor fileDescriptor = fileInputStream.getFD();
bitmap = mImageResizer.decodeSampledBitmapFromFileDescriptor(
fileDescriptor, reqWidth, reqHeight);
if (bitmap != null) {
addBitmapToMemoryCache(key, bitmap);
}
}2、ImageLoader
1)、图片压缩

2)、内存缓存和磁盘缓存

3)、同步加载和异步加载接口的设计

a、加载顺序:内存、磁盘、网络

b、检查线程是否为主线程:加载网络缓存时调用

c、使用线程池和Handler提供并发和访问UI的能力

3、使用ImageLoader

1)照片墙

2)列表卡顿的优化

a、异步加载耗时任务

b、控制异步任务执行频率:列表滑动时不加载图片

c、为Activity开启硬件加速: <span style="white-space:pre"> </span>android:hardwareAccelerated="true"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: