Bitmap的加载和Cache

一、Bitmap的高效加载

1、Bitmap的加载方式

1)、decodeFile

2)、decodeResource

3)、decodeStream

4)、decodeByteArray

2、BitmapFactory.Options缩放图片:采样率inSampleSize

1)、采样率取值:取值为2的指数,如果不是,则自动向下取整选择最接近的2的指数代替。

2)、采样率选择:缩放后的大小应大于ImageView大小,否则会由于拉伸导致模糊

3)、加载图片:

a、BitmapFactory.Options的inJustDecodeBounds设置为true并加载图片

b、从BitmapFactory.Options的outWidth和outHeight参数取出图片原始宽高

c、计算采样率

d、BitmapFactory.Options的inJustDecodeBounds设置为false并重新加载图片

二、Android中的缓存策略

1、缓存:

1)、概念:程序第一次从网络加载图片后,将其缓存到存储设备上,下次使用就不再从网络上获取了。为提高用户体验,还会在内存中缓存一份,这样请求图片时,首先去内存获取,没有则从存储设备获取,再没有则从网络加载。

2)、缓存策略:缓存的添加、获取和删除。常用算法:LRU

3)、LruCache

a、创建

<span style="white-space:pre">		</span>int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
		int cacheSize = maxMemory / 8;
		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
				// TODO Auto-generated method stub
				return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
			}
		};

b、获取、添加、删除一个缓存对象

<span style="white-space:pre">		</span>mMemoryCache.get(key);
		mMemoryCache.put(key, value);
		mMemoryCache.remove(key);

4)、DiskLruCache

a、创建

<span style="white-space:pre">		</span>File diskCacheDir = getDiskCacheDir(mContext, "bitmap");//获取缓存文件夹的方法
		if (!diskCacheDir.exists()) {
			diskCacheDir.mkdirs();
		}
		if (getUsableSpace(diskCacheDir) > DISK_CACHE_SIZE) {
			try {
				mDiskLruCache = DiskLruCache.open(diskCacheDir, 1, 1,
						DISK_CACHE_SIZE);
				mIsDiskLruCacheCreated = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
b、添加

	// 使用MD5算法获取字符串的Hash值//
	private String hashKeyFormUrl(String url) {
		String cacheKey;
		try {
			final MessageDigest mDigest = MessageDigest.getInstance("MD5");
			mDigest.update(url.getBytes());
			cacheKey = bytesToHexString(mDigest.digest());
		} catch (NoSuchAlgorithmException e) {
			cacheKey = String.valueOf(url.hashCode());
		}
		return cacheKey;
	}
	//将MD5字节数组转换成字符串
	private String bytesToHexString(byte[] bytes) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < bytes.length; i++) {
			String hex = Integer.toHexString(0xFF & bytes[i]);
			if (hex.length() == 1) {
				sb.append('0');
			}
			sb.append(hex);
		}
		return sb.toString();
	}
<span style="white-space:pre">		</span>//获取editor创建输出流,通过输出流将文件写入文件系统
		String key = hashKeyFormUrl(url);
		DiskLruCache.Editor editor = mDiskLruCache.edit(key);
		if (editor != null) {
			OutputStream outputStream = editor
					.newOutputStream(DISK_CACHE_INDEX);
			if (downloadUrlToStream(url, outputStream)) {
				editor.commit();
			} else {
				editor.abort();
			}
			mDiskLruCache.flush();
		}
	/**
	 * 将文件输出流写入文件系统
	 * 
	 * @param urlString
	 *            图片地址
	 * @param outputStream
	 *            输出流
	 * @return 写入结果状态
	 */
	public boolean downloadUrlToStream(String urlString,
			OutputStream outputStream) {
		HttpURLConnection urlConnection = null;
		BufferedOutputStream out = null;
		BufferedInputStream in = null;

		try {
			final URL url = new URL(urlString);
			urlConnection = (HttpURLConnection) url.openConnection();
			in = new BufferedInputStream(urlConnection.getInputStream(),
					IO_BUFFER_SIZE);
			out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);

			int b;
			while ((b = in.read()) != -1) {
				out.write(b);
			}
			return true;
		} catch (IOException e) {
			Log.e(TAG, "downloadBitmap failed." + e);
		} finally {
			if (urlConnection != null) {
				urlConnection.disconnect();
			}
			MyUtils.close(out);//关闭流的方法
			MyUtils.close(in);
		}
		return false;
	}
c、查找

<span style="white-space:pre">		</span>//查找缓存
		Bitmap bitmap = null;
		String key = hashKeyFormUrl(url);
		DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
		if (snapShot != null) {
			FileInputStream fileInputStream = (FileInputStream) snapShot
					.getInputStream(DISK_CACHE_INDEX);
			FileDescriptor fileDescriptor = fileInputStream.getFD();
			bitmap = mImageResizer.decodeSampledBitmapFromFileDescriptor(
					fileDescriptor, reqWidth, reqHeight);
			if (bitmap != null) {
				addBitmapToMemoryCache(key, bitmap);
			}
		}
2、ImageLoader

1)、图片压缩

2)、内存缓存和磁盘缓存

3)、同步加载和异步加载接口的设计

a、加载顺序:内存、磁盘、网络

b、检查线程是否为主线程:加载网络缓存时调用

c、使用线程池和Handler提供并发和访问UI的能力
3、使用ImageLoader

1)照片墙

2)列表卡顿的优化

a、异步加载耗时任务

b、控制异步任务执行频率:列表滑动时不加载图片

c、为Activity开启硬件加速:

 <span style="white-space:pre">		</span>android:hardwareAccelerated="true"








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值