【发布时间】:2016-10-09 22:23:20
【问题描述】:
我想像 instagram 那样加载很多图片,但仍然会出现 OutOfMemory,我的代码一次加载 18 张图片,并且可以向下滚动以加载更多图片。 我还将图像缓存到磁盘并在加载到位图之前调整图像大小以适合缩略图
private Bitmap loadBitmap(String id) throws IOException{
String key = id.toLowerCase();
// Check disk cache in background thread
Bitmap image = cacher.get(key);
if (image == null){
// Not found in disk cache
// Process as normal
if(!isCancelled()){
//download image to stream
ByteArrayOutputStream stream = new ByteArrayOutputStream();
DriveApiActivity.getService().files().get(id)
.executeMediaAndDownloadTo(stream);
//decode image to byte array
byte[] byteArray = stream.toByteArray();
stream.close();
//decode byte array to bitmap file
image = decodeToBitmap(
byteArray,
CustomCardView.width,
CustomCardView.height);
// Add final bitmap to caches
cacher.put(key, image);
}
}
return image;
}
Logcat 说异常来自 cacher.get() 方法
public Bitmap get(String key) {
synchronized (diskCacheLock) {
// Wait while disk cache is started from background thread
while (diskCacheStarting) {
try {
diskCacheLock.wait();
} catch (InterruptedException e) {
Toast.makeText(
context,
"getBitmapFromCache:" + e.getMessage(),
4).show();
}
}
if (diskLruCache != null) {
Bitmap bitmap = null;
DiskLruCache.Snapshot snapshot = null;
try{
snapshot = diskLruCache.get(key);
if(snapshot == null){
return null;
}
final InputStream in = snapshot.getInputStream(0);
if(in != null){
final BufferedInputStream buffIn =
new BufferedInputStream(in, Utils.IO_BUFFER_SIZE);
bitmap = BitmapFactory.decodeStream(buffIn);
}
}catch(IOException e){
e.printStackTrace();
}finally{
if(snapshot != null){
snapshot.close();
}
}
if(BuildConfig.DEBUG){
Log.d( "cache_test_DISK_", bitmap == null ? "" : "image read from disk " + key);
}
return bitmap;
}
}
return null;
}
此代码来自DiskLruCachegoogle 提供
【问题讨论】:
-
图片加载库有很多,为什么不用呢?
-
如果您真的想将大量图像加载到内存中,那么您很可能会遇到内存问题。与其尝试自己处理图像加载,不如考虑使用库,例如picasso (square.github.io/picasso) 然后使用加载图像:
Picasso.with(context).load("http://path/to/image.png").fit().into(imageView);这将减小加载位图的大小并可能节省大量内存。 -
我想练习处理缓存和内存。不知道难不难
标签: java android caching bitmap out-of-memory