Android下的图片缓存简单实现(避免软引用缓存)
来源:互联网 发布:淘宝运营公司那家强 编辑:程序博客网 时间:2024/06/05 19:17
在工作中,经常会遇到这样的情况,安卓客户端从服务器上获取图片并进行显示,但很多网络请求并不是理想的,事实上,网络请求时很耗时的,所以需要我们把图片保存到本地,等到服务器上的资源加载上以后,在显示出来,这样就会给用户一种比较流畅的感觉。
本类中通过两种方式来实现图片的缓存
- 通过Soft References来缓存图片(API不建议使用此类缓存图片)
- 将图片保存到本地磁盘缓存图片
缓存的逻辑如下:
- 先把图片等资源保存到本地
- 获取服务器图片
- 将服务器图片等资源显示到客户端上
- 在将新的图片等资源保存到本地
package com.loopj.image;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.lang.ref.SoftReference;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;public class WebImageCache { private static final String DISK_CACHE_PATH = "/web_image_cache/"; private ConcurrentHashMap<String, SoftReference<Bitmap>> memoryCache; private String diskCachePath; private boolean diskCacheEnabled = false; private ExecutorService writeThread; public WebImageCache(Context context) { // Set up in-memory cache store memoryCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>(); // Set up disk cache store Context appContext = context.getApplicationContext(); diskCachePath = appContext.getCacheDir().getAbsolutePath() + DISK_CACHE_PATH; File outFile = new File(diskCachePath); outFile.mkdirs(); diskCacheEnabled = outFile.exists(); // Set up threadpool for image fetching tasks writeThread = Executors.newSingleThreadExecutor(); } public Bitmap get(final String url) { Bitmap bitmap = null; // Check for image in memory bitmap = getBitmapFromMemory(url); // Check for image on disk cache if(bitmap == null) { bitmap = getBitmapFromDisk(url); // Write bitmap back into memory cache if(bitmap != null) { cacheBitmapToMemory(url, bitmap); } } return bitmap; } public void put(String url, Bitmap bitmap) { cacheBitmapToMemory(url, bitmap); cacheBitmapToDisk(url, bitmap); } public void remove(String url) { if(url == null){ return; } // Remove from memory cache memoryCache.remove(getCacheKey(url)); // Remove from file cache File f = new File(diskCachePath, getCacheKey(url)); if(f.exists() && f.isFile()) { f.delete(); } } public void clear() { // Remove everything from memory cache memoryCache.clear(); // Remove everything from file cache File cachedFileDir = new File(diskCachePath); if(cachedFileDir.exists() && cachedFileDir.isDirectory()) { File[] cachedFiles = cachedFileDir.listFiles(); for(File f : cachedFiles) { if(f.exists() && f.isFile()) { f.delete(); } } } } private void cacheBitmapToMemory(final String url, final Bitmap bitmap) { memoryCache.put(getCacheKey(url), new SoftReference<Bitmap>(bitmap)); } private void cacheBitmapToDisk(final String url, final Bitmap bitmap) { writeThread.execute(new Runnable() { @Override public void run() { if(diskCacheEnabled) { BufferedOutputStream ostream = null; try { ostream = new BufferedOutputStream(new FileOutputStream(new File(diskCachePath, getCacheKey(url))), 2*1024); bitmap.compress(CompressFormat.PNG, 100, ostream); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { try { if(ostream != null) { ostream.flush(); ostream.close(); } } catch (IOException e) {} } } } }); } private Bitmap getBitmapFromMemory(String url) { Bitmap bitmap = null; SoftReference<Bitmap> softRef = memoryCache.get(getCacheKey(url)); if(softRef != null){ bitmap = softRef.get(); } return bitmap; } private Bitmap getBitmapFromDisk(String url) { Bitmap bitmap = null; if(diskCacheEnabled){ String filePath = getFilePath(url); File file = new File(filePath); if(file.exists()) { bitmap = BitmapFactory.decodeFile(filePath); } } return bitmap; } private String getFilePath(String url) { return diskCachePath + getCacheKey(url); } private String getCacheKey(String url) { if(url == null){ throw new RuntimeException("Null url passed in"); } else { return url.replaceAll("[.:/,%?&=]", "+").replaceAll("[+]+", "+"); } }}
本类用到了图片的软引用技术,加载图片时
- 先从软引用里面加载图片;
- 如果软引用里面没有图片,在从内存中加载图片
软引用(SoftReference)
看看API是如何解释的:
/* A reference that is cleared when its referent is not strongly
reachable and * there is memory pressure. * *Avoid Soft
* In practice, soft references are
References for Caching
inefficient for caching. The runtime doesn’t * have enough
information on which references to clear and which to keep. Most *
fatally, it doesn’t know what to do when given the choice between
clearing a * soft reference and growing the heap. * *The lack
of information on the value to your application of each reference *
limits the usefulness of soft references. References that are cleared
too * early cause unnecessary work; those that are cleared too late
waste memory. * *Most applications should use an {@code
android.util.LruCache} instead of * soft references. LruCache has an
effective eviction policy and lets the user * tune how much memory is
allotted.
上面这段话的大概意思就是说不建议使用软引用进行缓存,软引用是inefficient的。因为不知道什么时候就被垃圾回收器回收了。
建议使用android.util.LruCache(强引用)来进行缓存。 以后在讲讲软引用,强引用。
1 0
- Android下的图片缓存简单实现(避免软引用缓存)
- Android下实现图片缓存的实例
- Android下实现图片缓存的实例
- 【Android】通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android通过软引用实现图片缓存,防止内存溢出
- Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))
- Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))
- Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))
- Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))
- Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))
- Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))
- image 相机vc+环境配置
- BestCoder Round #64 (div.2) HDOJ5585 Numbers(模拟)
- Ubuntu 14.04.2 移植FFmpeg 2.8.3 到Android平台
- TCP/IP详解卷1 读书笔记:第十八章 TCP连接的建立与终止
- 终于学会了在github上创建一个release、tag了
- Android下的图片缓存简单实现(避免软引用缓存)
- oauth认证四种模式中的第一种oauthation code模式
- POJ A Simple Problem with Integers 3468(线段树区间更新)
- 在MAC上配置SVN服务器 图文教程
- 安卓开发技术:监听软键盘的显示与隐藏
- JDBCUtils动手实现自己的JDBC工具类之二(实践篇)
- 单链表 C++实现
- cocos2d-x 学习笔记3
- 仿蘑菇街个人主页