android远程图片获取和本地缓存

上传人:第*** 文档编号:30593615 上传时间:2018-01-30 格式:DOC 页数:17 大小:148KB
返回 下载 相关 举报
android远程图片获取和本地缓存_第1页
第1页 / 共17页
android远程图片获取和本地缓存_第2页
第2页 / 共17页
android远程图片获取和本地缓存_第3页
第3页 / 共17页
android远程图片获取和本地缓存_第4页
第4页 / 共17页
android远程图片获取和本地缓存_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《android远程图片获取和本地缓存》由会员分享,可在线阅读,更多相关《android远程图片获取和本地缓存(17页珍藏版)》请在金锄头文库上搜索。

1、对于客户端服务器端应用,从远程获取图片算是经常要用的一个功能,而图片资源往往会消耗比较大的流量,对应用来说,如果处理不好这个问题,那会让用户很崩溃,不知不觉手机流量就用完了,等用户发现是你的应用消耗掉了他手机流量的话,那么可想而知你的应用将面临什么样的命运。AD: 另外一个问题就是加载速度,如果应用中图片加载速度很慢的话,那么用户同样会等到崩溃。那么如何处理好图片资源的获取和管理呢?异步下载本地缓存异步下载大家都知道,在 android 应用中 UI 线程 5 秒没响应的话就会抛出无响应异常,对于远程获取大的资源来说,这种异常还是很容易就会抛出来的,那么怎么避免这种问题的产生。在 androi

2、d 中提供两种方法来做这件事情:启动一个新的线程来获取资源,完成后通过 Handler 机制发送消息,并在 UI 线程中处理消息,从而达到在异步线程中获取图片,然后通过 Handler Message来更新 UI 线程的过程。使用 android 中提供的 AsyncTask 来完成。具体的做法这里就不介绍了,查下 API 就可以了,或者是 google、baidu 下。这里主要来说本地缓存。本地缓存对于图片资源来说,你不可能让应用每次获取的时候都重新到远程去下载(ListView),这样会浪费资源,但是你又不能让所有图片资源都放到内存中去(虽然这样加载会比较快),因为图片资源往往会占用很大的

3、内存空间,容易导致 OOM。那么如果下载下来的图片保存到 SDCard 中,下次直接从 SDCard 上去获取呢?这也是一种做法,我看了下,还是有不少应用采用这种方式的。采用LRU 等一些算法可以保证 sdcard 被占用的空间只有一小部分,这样既保证了图片的加载、节省了流量、又使 SDCard 的空间只占用了一小部分。另外一种做法是资源直接保存在内存中,然后设置过期时间和 LRU 规则。sdcard 保存:在 sdcard 上开辟一定的空间,需要先判断 sdcard 上剩余空间是否足够,如果足够的话就可以开辟一些空间,比如 10M当需要获取图片时,就先从 sdcard 上的目录中去找,如果找

4、到的话,使用该图片,并更新图片最后被使用的时间。如果找不到,通过 URL 去 download去服务器端下载图片,如果下载成功了,放入到 sdcard 上,并使用,如果失败了,应该有重试机制。比如 3 次。下载成功后保存到 sdcard 上,需要先判断 10M 空间是否已经用完,如果没有用完就保存,如果空间不足就根据 LRU 规则删除一些最近没有被用户的资源。关键代码:保存图片到 SD 卡上1. private void saveBmpToSd(Bitmap bm, Stringurl) 2. if (bm = null) 3. Log.w(TAG, trying to savenull bi

5、tmap); 4. return; 5. 6. /判断 sdcard 上的空间 7. if (FREE_SD_SPACE_NEEDED_TO_CACHE freeSpaceOnSd() 8. Log.w(TAG, Low free space onsd, do not cache); 9. return; 10. 11. String filename =convertUrlToFileName(url); 12. String dir = getDirectory(filename); 13. File file = new File(dir +/ + filename); 14. try

6、15. file.createNewFile(); 16. OutputStream outStream = newFileOutputStream(file); 17. press(Bitmap.CompressFormat.JPEG, 100, outStream); 18. outStream.flush(); 19. outStream.close(); 20. Log.i(TAG, Image saved tosd); 21. catch (FileNotFoundException e) 22. Log.w(TAG,FileNotFoundException); 23. catch

7、 (IOException e) 24. Log.w(TAG,IOException); 25. 26. 计算 sdcard 上的空间:1. /* 2. * 计算 sdcard 上的剩余空间 3. * return 4. */ 5. private int freeSpaceOnSd() 6. StatFs stat = newStatFs(Environment.getExternalStorageDirectory() .getPath(); 7. double sdFreeMB = (double)stat.getAvailableBlocks() * (double) stat.get

8、BlockSize() / MB; 8. return (int) sdFreeMB; 9. 修改文件的最后修改时间1. /* 2. * 修改文件的最后修改时间 3. * param dir 4. * param fileName 5. */ 6. private void updateFileTime(String dir,String fileName) 7. File file = new File(dir,fileName); 8. long newModifiedTime =System.currentTimeMillis(); 9. file.setLastModified(new

9、ModifiedTime); 10. 本地缓存优化1. /* 2. *计算存储目录下的文件大小,当文件总大小大于规定的 CACHE_SIZE或者 sdcard 剩余空间小于 FREE_SD_SPACE_NEEDED_TO_CACHE 的规定 3. * 那么删除 40%最近没有被使用的文件 4. * param dirPath 5. * param filename 6. */ 7. private void removeCache(String dirPath) 8. File dir = new File(dirPath); 9. File files = dir.listFiles();

10、10. if (files = null) 11. return; 12. 13. int dirSize = 0; 14. for (int i = 0; i CACHE_SIZE * MB |FREE_SD_SPACE_NEEDED_TO_CACHE freeSpaceOnSd() 20. int removeFactor = (int) (0.4 *files.length) + 1); 21. 22. Arrays.sort(files, newFileLastModifSort(); 23. 24. Log.i(TAG, Clear some expiredcache files )

11、; 25. 26. for (int i = 0; i mTimeDiff) 49. 50. Log.i(TAG, Clear some expiredcache files ); 51. 52. file.delete(); 53. 54. 55. 56. 文件使用时间排序1. /* 2. * TODO 根据文件的最后修改时间进行排序 * 3. */ 4. classFileLastModifSort implements Comparator 5. public int compare(File arg0, File arg1) 6. if (arg0.lastModified() arg

12、1.lastModified() 7. return 1; 8. else if (arg0.lastModified() =arg1.lastModified() 9. return 0; 10. else 11. return -1; 12. 13. 14. 内存保存:在内存中保存的话,只能保存一定的量,而不能一直往里面放,需要设置数据的过期时间、LRU 等算法。这里有一个方法是把常用的数据放到一个缓存中(A),不常用的放到另外一个缓存中(B)。当要获取数据时先从 A 中去获取,如果 A 中不存在那么再去 B 中获取。B 中的数据主要是 A 中 LRU 出来的数据,这里的内存回收主要针对

13、B 内存,从而保持 A 中的数据可以有效的被命中。先定义 A 缓存:1. private final HashMapmHardBitmapCache = new LinkedHashMap(HARD_CACHE_CAPACITY/ 2, 0.75f, true) 2. Override 3. protected booleanremoveEldestEntry(LinkedHashMap.Entry eldest) 4. if (size() HARD_CACHE_CAPACITY) 5. /当 map 的 size 大于 30 时,把最近不常用的 key 放到 mSoftBitmapCach

14、e 中,从而保证 mHardBitmapCache 的效率 6. mSoftBitmapCache.put(eldest.getKey(), newSoftReference(eldest.getValue(); 7. return true; 8. else 9. return false; 10. 11. ; 再定于 B 缓存:1. /* 2. *当 mHardBitmapCache 的 key 大于 30 的时候,会根据 LRU 算法把最近没有被使用的 key 放入到这个缓存中。 3. *Bitmap 使用了 SoftReference,当内存空间不足时,此 cache 中的 bitmap 会被垃圾回收掉 4. */ 5. private final staticConcurrentHas

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 外语文库 > 英语学习

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号