少年击剑更吹箫,剑气箫心一例消。这篇文章主要讲述安卓权威编程指南 挑战练习 24章 预加载以及缓存相关的知识,希望能为你提供帮助。
24.7 挑战练习:预加载以及缓存
应用中并非所有任务都能即时完成,对此,大多用户表示理解。不过,即使是这样,开发者们也一直在努力做到最好。为了让应用反应更快,大多数现实应用都通过以下两种方式增强自己的代码:? 增加缓存层
? 预加载图片
缓存指存储一定数目 Bitmap 对象的地方。这样,即使不再使用这些对象,它们也依然存储在那里。
缓存的存储空间有限,因此,在缓存空间用完的情况下,需要某种策略对保存的对象做一定的取舍。许多缓存机制使用一种叫作LRU(least recently used,最近最少使用)的存储策略。基于该种策略,当存储空间用尽时,缓存会清除最近最少使用的对象。android支持库中的 LruCache 类实现了LRU缓存策略。
作为第一个挑战练习,请使用LruCache 为 ThumbnailDownloader 增加简单的缓存功能。这样,每次下载完 Bitmap 时,将其存入缓存中。随后,准备下载新图片时,应首先查看缓存,确认它是否存在。缓存实现完成后,即可使用它进行预加载。预加载是指在实际使用对象前,就预先将处理对象加载到缓存中。
这样,在显示 Bitmap 时,就不会存在下载延迟。实现完美的预加载比较棘手,但对用户来说,良好的预加载是一种截然不同的体验。作为第二个稍有难度的挑战练习,请在显示 GalleryItem 时,为前十个和接下来十个 GalleryItem 预加载 Bitmap
1.增加缓存层
在ThumbnailDownloader增加:
private LruCache< String, Bitmap> mBitmapLruCache;
在onLooperPrepared()方法中实例化这一对象:
//onLooperPrepared()在Looper首次检查消息队列之前调用的。 @Override protected void onLooperPrepared() { mRequestHandler = new Handler() { @Override public void handleMessage(Message msg) {//队列中的下载消息取出并可以处理时,就会触发调用Handler.handleMessage()方法。 if (msg.what == MESSAGE_DOWNLOAD) { T target = (T) msg.obj; Log.i(TAG, "Got a request for URL" + mRequestMap.get(target)); handleRequest(target); } } }; mBitmapLruCache = new LruCache< String, Bitmap> (24 * 1024); //实际中,LruCache分配的内存应该进行动态计算 }
修改handleRequest()方法:
private void handleRequest(final T target) { try { final String url = mRequestMap.get(target); final Bitmap bitmap; if (url == null) { return; }if (mBitmapLruCache.get(url) != null) { bitmap = mBitmapLruCache.get(url); } else { byte[] bitmapBytes = new FlickrFetcher().getUrlBytes(url); bitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length); //将返回的字节数组转化为位图 }if (mBitmapLruCache.get(url) == null) { mBitmapLruCache.put(url, bitmap); Log.d(TAG, "handleRequest:Put ---"+ url); } Log.i(TAG, "Bitmap Created"); mResponseHandler.post(new Runnable() { @Override public void run() { if (mRequestMap.get(target) != url || mHasQuit) {//再次检查requestMap 因为RecyclerView会循环使用其视图, return; } mRequestMap.remove(target); //在requesMap中删除配对的PhotoHolder-URL mThumbnailDownloadListener.onThumnailDownloaded(target, bitmap); } }); } catch (IOException ioe) { Log.e(TAG, "Error downloading image", ioe); } }
2.预加载:
PhotoGalleryFragment中
@Override public void onBindViewHolder(PhotoHolder photoHolder, int position) {GalleryItem galleryItem = mGalleryItems.get(position); Drawable placeholder = getResources().getDrawable(R.drawable.bill_up_close); photoHolder.bindDrawable(placeholder); mThumbnailDownloader.queueThumbnail(photoHolder, galleryItem.getUrl()); for(int i=position-10; i< position + 10; i++) {//这里必须要put进LruCache之后才会显示图片。十分耗时 if (i < 0 || i == position || i > = mItems.size()) { continue; } GalleryItem item = mGalleryItems.get(i); mThumbnailDownloader.putUrl(item.getUrl()); } }
ThumbnailDownloader中:
public void putUrl(final String url){ if(mBitmapLruCache.get(url) == null){ new Thread(new Runnable() { @Override public void run() { try{ byte[] bitmapBytes = new FlickrFetcher().getUrlBytes(url); Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length); mBitmapLruCache.put(url,bitmap); }catch(Exception e){ e.printStackTrace(); } } }).start(); } }
【安卓权威编程指南 挑战练习 24章 预加载以及缓存】
推荐阅读
- 安卓权威编程指南 挑战练习(第26章 在 Lollipop 设备上使用 JobService)
- 10个最佳反向图像搜索引擎和应用程序推荐合集
- 10大最佳免费和付费音乐下载软件推荐合集(哪个最好用())
- Android和iPhone的10个最佳表情符号应用程序(免费下载??)
- 你应该尝试的10个PC最佳GBA模拟器推荐合集(你喜欢哪个())
- 12款PC体验高强度战斗的最佳策略游戏推荐合集(哪些最好())
- 27款无界游戏的最佳上古卷轴V(天际模组推荐合集)
- 文明5冒险的20个最令人惊叹的模组推荐合集(哪个最好())
- 14款最佳游戏推荐合集(如《疯狂战斗守望先锋》)