Android 图片下载本地内存的缓存方式

 

 Android 图片下载本地内存的缓存方式

在内存中保存的话,只能保存一定的量,而不能一直往里面放,需要设置数据的过期时间、LRU等算法。这里有一个方法是把常用的数据放到一个缓存中(A),不常用的放到另外一个缓存中(B)。当要获取数据时先从A中去获取,如果A中不存在那么再去B中获取。B中的数据主要是ALRU出来的数据,这里的内存回收主要针对B内存,从而保持A中的数据可以有效的被命中。
 

先定义A缓存:

java代码:

private final HashMap<String, Bitmap>mHardBitmapCache = new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY/ 2, 0.75f, true) {
@Override
protected booleanremoveEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {
if (size() >HARD_CACHE_CAPACITY) {
//mapsize大于30时,把最近不常用的key放到mSoftBitmapCache中,从而保证mHardBitmapCache的效率
mSoftBitmapCache.put(eldest.getKey(), newSoftReference<Bitmap>(eldest.getValue()));
return true;
} else
return false;
}
};
再定义B缓存:

java代码:

/**
*mHardBitmapCachekey大于30的时候,会根据LRU算法把最近没有被使用的key放入到这个缓存中。
*Bitmap使用了SoftReference,当内存空间不足时,此cache中的bitmap会被垃圾回收掉
*/
private final staticConcurrentHashMap<String, SoftReference<Bitmap>> mSoftBitmapCache =new ConcurrentHashMap

从缓存中获取数据:

java代码:

/**
从缓存中获取图片
*/
private Bitmap getBitmapFromCache(Stringurl) {
// 先从mHardBitmapCache缓存中获取
synchronized (mHardBitmapCache) {
final Bitmap bitmap =mHardBitmapCache.get(url);
if (bitmap != null) {
//如果找到的话,把元素移到linkedhashmap的最前面,从而保证在LRU算法中是最后被删除
mHardBitmapCache.remove(url);
mHardBitmapCache.put(url,bitmap);
return bitmap;
}
}
//如果mHardBitmapCache中找不到,到mSoftBitmapCache中找

SoftReference<Bitmap>bitmapReference = mSoftBitmapCache.get(url);
if (bitmapReference != null) {
final Bitmap bitmap =bitmapReference.get();
if (bitmap != null) {
return bitmap;
} else {
mSoftBitmapCache.remove(url);
}
}
return null;
}
  如果缓存中不存在,那么就只能去服务器端去下载:

java代码:

/**
异步下载图片
*/
class ImageDownloaderTask extendsAsyncTask<String, Void, Bitmap> {
private static final int IO_BUFFER_SIZE= 4 * 1024;
private String url;
private finalWeakReference<ImageView> imageViewReference;
public ImageDownloaderTask(ImageViewimageView) {
imageViewReference = newWeakReference<ImageView>(imageView);
}

@Override
protected BitmapdoInBackground(String... params) {
final AndroidHttpClient client =AndroidHttpClient.newInstance("Android");
url = params[0];
final HttpGet getRequest = newHttpGet(url);
try {
HttpResponse response =client.execute(getRequest);
final int statusCode =response.getStatusLine().getStatusCode();
if (statusCode !=HttpStatus.SC_OK) {
Log.w(TAG, "" +url + "中下载图片时出错!,错误码:" + statusCode);
return null;
}
final HttpEntity entity =response.getEntity();
if (entity != null) {
InputStream inputStream =null;
OutputStream outputStream =null;
try {
inputStream =entity.getContent();
finalByteArrayOutputStream dataStream = new ByteArrayOutputStream();
outputStream = newBufferedOutputStream(dataStream, IO_BUFFER_SIZE);
copy(inputStream,outputStream);
outputStream.flush();
final byte[] data =dataStream.toByteArray();
final Bitmap bitmap =BitmapFactory.decodeByteArray(data, 0, data.length);
return bitmap;
} finally {
if (inputStream !=null) {

inputStream.close();
}
if (outputStream !=null) {
outputStream.close();
}
entity.consumeContent();
}
}
} catch (IOException e) {
getRequest.abort();
Log.w(TAG, "I/O errorwhile retrieving bitmap from " + url, e);
} catch (IllegalStateException e) {
getRequest.abort();
Log.w(TAG, "Incorrect URL:" + url);
} catch (Exception e) {
getRequest.abort();
Log.w(TAG, "Error whileretrieving bitmap from " + url, e);
} finally {
if (client != null) {
client.close();
}
}
return null;
}

 

主要信息来源   移动开发者联盟

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android中头像本地缓存可以通过使用SharedPreferences或者使用磁盘缓存方式实现。 1. 使用SharedPreferences缓存头像: 可以将头像图片转化成Base64编码的字符串,然后将其保存在SharedPreferences中。当需要加载头像时,从SharedPreferences中读取Base64字符串,再将其转化为Bitmap对象。 具体实现代码如下: ``` //保存头像到SharedPreferences中 public void saveAvatarToSharedPreferences(Bitmap bitmap) { SharedPreferences sharedPreferences = getSharedPreferences("avatar", MODE_PRIVATE); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); String avatarBase64 = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("avatar", avatarBase64); editor.apply(); } //从SharedPreferences中加载头像 public Bitmap loadAvatarFromSharedPreferences() { SharedPreferences sharedPreferences = getSharedPreferences("avatar", MODE_PRIVATE); String avatarBase64 = sharedPreferences.getString("avatar", null); if (avatarBase64 != null) { byte[] bytes = Base64.decode(avatarBase64, Base64.DEFAULT); return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } return null; } ``` 2. 使用磁盘缓存方式缓存头像: 可以使用Android中的LruCache或者DiskLruCache类来实现磁盘缓存头像。LruCache是一种内存缓存,而DiskLruCache则是一种磁盘缓存。 具体实现代码如下: ``` //初始化DiskLruCache private void initDiskLruCache() throws IOException { File cacheDir = getExternalCacheDir(); if (cacheDir != null) { int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; diskLruCache = DiskLruCache.open(cacheDir, versionCode, 1, 10 * 1024 * 1024); } } //保存头像到DiskLruCache中 public void saveAvatarToDiskLruCache(String key, Bitmap bitmap) throws IOException { if (diskLruCache == null) { initDiskLruCache(); } if (diskLruCache != null) { DiskLruCache.Editor editor = diskLruCache.edit(key); if (editor != null) { OutputStream outputStream = editor.newOutputStream(0); bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); editor.commit(); } } } //从DiskLruCache中加载头像 public Bitmap loadAvatarFromDiskLruCache(String key) throws IOException { if (diskLruCache == null) { initDiskLruCache(); } if (diskLruCache != null) { DiskLruCache.Snapshot snapshot = diskLruCache.get(key); if (snapshot != null) { InputStream inputStream = snapshot.getInputStream(0); return BitmapFactory.decodeStream(inputStream); } } return null; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值