三级缓存详解

来源:互联网 发布:js写网站好不好 编辑:程序博客网 时间:2024/06/05 07:41

Android 开发中对图片的加载恨常见,为了防止出现内存溢出,采用三级缓存:

    内存缓存,

    本地缓存(sd),

    网络缓存。

  从网络下载的图片保存到内存和sd卡中,之后调用可以直接从内存或者sd卡读出

/** * 内存缓存 * @author xiongt * */public class MemoryCacheUtils {private LruCache<String, Bitmap> mMemoryCache;public MemoryCacheUtils() {long maxMemory = Runtime.getRuntime().maxMemory(); // 8;// 模拟器默认是16MmMemoryCache = new LruCache<String, Bitmap>((int)(maxMemory)){@Overrideprotected int sizeOf(String key, Bitmap value) {int byteCount = value.getRowBytes()*value.getHeight();//获取图片占用内存大小return byteCount;}};}/** * 从内存读 * @param url * @return */public Bitmap getBitmapFromMemory(String url){return mMemoryCache.get(url);}/** * 写内存 */public void setBitmapToMemory(String url,Bitmap bitmap){mMemoryCache.put(url, bitmap);}}
/** * 本地缓存(sd卡) * @author xiongt * */public class LocalCacheUtils {public static final String CACHE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath()+"/kdumpda_data";/** * 向SD卡写图片 * @param url * @param bitmap */public void setBitmapToLocal(String url,Bitmap bitmap){try {//String fileName =  MD5Encoder.encode(url);String fileName = url;File file = new File(CACHE_PATH, fileName);File fileParent = file.getParentFile();if(!fileParent.exists()){// 如果文件夹不存在, 创建文件夹fileParent.mkdirs();}//将图片保存到本地bitmap.compress(CompressFormat.JPEG, 100,new FileOutputStream(file));} catch (FileNotFoundException e) {e.printStackTrace();}}/** * 从SD卡读图片 */public Bitmap getBitmapFromLocal(String url){try {String fileName = url;File file = new File(CACHE_PATH, fileName);if(file.exists()){Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));return bitmap;}} catch (FileNotFoundException e) {e.printStackTrace();}return null;}}
/** * 网络缓存 * @author xiongt * */public class NetCacheUtils {private LocalCacheUtils mLocalCacheUtils;private MemoryCacheUtils mMemoryCacheUtils;public NetCacheUtils(LocalCacheUtils mLocalCacheUtils,MemoryCacheUtils mMemoryCacheUtils) {this.mLocalCacheUtils = mLocalCacheUtils;this.mMemoryCacheUtils = mMemoryCacheUtils;}//根据图片的url去加载图片//在本地和内存中缓存/** * 从网络下载图片(异步) * @param ivPic * @param url * @return */public void getBitmapFromNet(ImageView ivPic,String url){new BitmapTask().execute(ivPic,url);//启动AsyncTask,参数在doInBackground中获取}/** * 异步任务是 Handler 和线程池的封装 * 泛型,第一个是参数,第二个是进度更新,第三个是返回结果 * @author xiongt * */class BitmapTask extends AsyncTask<Object, Void, Bitmap>{private ImageView ivPic;private String url;/** * 更新进度,主线程 */@Overrideprotected void onProgressUpdate(Void... values) {super.onProgressUpdate(values);//在doInBackground中调用publishProgress()方法更新}        /**         * 后台耗时方法在此进行,子线程         */@Overrideprotected Bitmap doInBackground(Object... params) {ivPic = (ImageView) params[0];url = (String) params[1];ivPic.setTag(url);// 将url和imageview绑定return downloadBitmap(url);}/** * 耗时操作完成后,执行该方法,主线程 */@Overrideprotected void onPostExecute(Bitmap result) {if(result != null){String bindUrl = (String) ivPic.getTag();if(url.equals(bindUrl)){// 确保图片设定给了正确的imageviewivPic.setImageBitmap(result);mLocalCacheUtils.setBitmapToLocal(url, result);// 将图片保存在本地                    mMemoryCacheUtils.setBitmapToMemory(url, result);// 将图片保存在内存}}super.onPostExecute(result);}}/** * 下载图片 * @param url * @return */public Bitmap downloadBitmap(String url) {HttpURLConnection conn = null;try {conn = (HttpURLConnection) new URL(url).openConnection();conn.setConnectTimeout(5000);conn.setReadTimeout(5000);conn.setRequestMethod("GET");conn.connect();int responseCode = conn.getResponseCode();if(responseCode == 200){InputStream inputStream = conn.getInputStream();//图片压缩处理BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;//宽高都压缩为原来的二分之一, 此参数需要根据图片要展示的大小来确定options.inPreferredConfig = Bitmap.Config.ARGB_8888;//设置图片格式Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);return bitmap;}} catch (Exception e) {e.printStackTrace();} finally{conn.disconnect();}return null;}}





0 0
原创粉丝点击