三级缓存详解

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

    内存缓存,

    本地缓存(sd),

    网络缓存。

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

/**
 * 内存缓存
 * @author xiongt
 *
 */
public class MemoryCacheUtils {
	private LruCache<String, Bitmap> mMemoryCache;

	public MemoryCacheUtils() {
		long maxMemory = Runtime.getRuntime().maxMemory(); // 8;// 模拟器默认是16M
		mMemoryCache = new LruCache<String, Bitmap>((int)(maxMemory)){
			@Override
			protected 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;
		/**
		 * 更新进度,主线程
		 */
		@Override
		protected void onProgressUpdate(Void... values) {
			super.onProgressUpdate(values);//在doInBackground中调用publishProgress()方法更新
		}
        /**
         * 后台耗时方法在此进行,子线程
         */
		@Override
		protected Bitmap doInBackground(Object... params) {
			ivPic = (ImageView) params[0];
			url = (String) params[1];
			ivPic.setTag(url);// 将url和imageview绑定
			return downloadBitmap(url);
		}
		/**
		 * 耗时操作完成后,执行该方法,主线程
		 */
		@Override
		protected void onPostExecute(Bitmap result) {
			if(result != null){
				String bindUrl = (String) ivPic.getTag();
				if(url.equals(bindUrl)){// 确保图片设定给了正确的imageview
					ivPic.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;
	}




}







  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值