




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
对于客户端 服务器端应用 从远程获取图片算是经常要用的一个功能 而 图片资源往往会消耗比较大的流量 对应用来说 如果处理不好这个问题 那 会让用户很崩溃 不知不觉手机流量就用完了 等用户发现是你的应用消耗掉 了他手机流量的话 那么可想而知你的应用将面临什么样的命运 AD 另外一个问题就是加载速度 如果应用中图片加载速度很慢的话 那么用户同 样会等到崩溃 那么如何处理好图片资源的获取和管理呢 异步下载 本地缓存 异步下载 大家都知道 在 android 应用中 UI 线程 5 秒没响应的话就会抛出无响应异常 对于远程获取大的资源来说 这种异常还是很容易就会抛出来的 那么怎么避 免这种问题的产生 在 android 中提供两种方法来做这件事情 启动一个新的线程来获取资源 完成后通过 Handler 机制发送消息 并在 UI 线 程中处理消息 从而达到在异步线程中获取图片 然后通过 Handler Message 来更新 UI 线程的过程 使用 android 中提供的 AsyncTask 来完成 具体的做法这里就不介绍了 查下 API 就可以了 或者是 google baidu 下 这里主要来说本地缓存 本地缓存 对于图片资源来说 你不可能让应用每次获取的时候都重新到远程去下载 ListView 这样会浪费资源 但是你又不能让所有图片资源都放到内存中去 虽然这样加载会比较快 因为图片资源往往会占用很大的内存空间 容易导 致 OOM 那么如果下载下来的图片保存到 SDCard 中 下次直接从 SDCard 上去 获取呢 这也是一种做法 我看了下 还是有不少应用采用这种方式的 采用 LRU 等一些算法可以保证 sdcard 被占用的空间只有一小部分 这样既保证了图 片的加载 节省了流量 又使 SDCard 的空间只占用了一小部分 另外一种做法 是资源直接保存在内存中 然后设置过期时间和 LRU 规则 sdcard 保存 在 sdcard 上开辟一定的空间 需要先判断 sdcard 上剩余空间是否足够 如果 足够的话就可以开辟一些空间 比如 10M 当需要获取图片时 就先从 sdcard 上的目录中去找 如果找到的话 使用该图 片 并更新图片最后被使用的时间 如果找不到 通过 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 bitmap 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 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 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 getBlockSize 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 newModifiedTime 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 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 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 arg1 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 出来的数据 这里的内 存回收主要针对 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 放 到 mSoftBitmapCache 中 从而保证 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 staticConcurrentHashMap String SoftReference mSoftBitmapCache new ConcurrentHashMap String SoftReference HARD CACHE CAPA CITY 2 从缓存中获取数据 1 2 从缓存中获取图片 3 4 private Bitmap getBitmapFromCache Stringurl 5 先从 mHardBitmapCache 缓存中获取 6 synchronized mHardBitmapCache 7 final Bitmap bitmap mHardBitmapCache get url 8 if bitmap null 9 如果找到的话 把元素移到 linkedhashmap 的最 前面 从而保证在 LRU 算法中是最后被删除 10 mHardBitmapCache remove url 11 mHardBitmapCache put url bitmap 12 return bitmap 13 14 15 如果 mHardBitmapCache 中找不到 到 mSoftBitmapCache 中找 16 SoftReferencebitmapReference mSoftBitmapCache get url 17 if bitmapReference null 18 final Bitmap bitmap bitmapReference get 19 if bitmap null 20 return bitmap 21 else 22 mSoftBitmapCache remove url 23 24 25 return null 26 如果缓存中不存在 那么就只能去服务器端去下载 1 2 异步下载图片 3 4 class ImageDownloaderTask extendsAsyncTask 5 private static final int IO BUFFER SIZE 4 1024 6 private String url 7 private finalWeakReference imageViewReference 8 public ImageDownloaderTask ImageViewimageView 9 imageViewReference newWeakReference imageView 10 11 12 Override 13 protected BitmapdoInBackground String params 14 final AndroidHttpClient client AndroidHttpClient newInstance Android 15 url params 0 16 final HttpGet getRequest newHttpGet url 17 try 18 HttpResponse response client execute getRequest 19 final int statusCode response getStatusLine getStatusCode 20 if statusCode HttpStatus SC OK 21 Log w TAG 从 url 中下载图片时出错 错 误码 statusCode 22 return null 23 24 final HttpEntity entity response getEntity 25 if entity null 26 InputStream inputStream null 27 OutputStream outputStream null 28 try 29 inputStream entity getContent 30 finalByteArrayOutputStream dataStream new ByteArrayOutputStream 31 outputStream newBufferedOutputStream dataStream IO BUFFER SIZE 32 copy inputStream outputStream 33 outputStream flush 34 final byte data dataStream toByteArray 35 final Bitmap bitmap BitmapFactory decodeByteArray data 0 data length 36 return bitmap 37 finally 38 if inputStream null 39 inputStream close 40 41 if outputStream null 42 outputStream close 43 44 entity consumeContent 45 46 47 catch IOException e 48 getRequest abort 49 Log w TAG I O errorwhile retrieving bitmap from url e 50 catch IllegalStateException e 51 getRequest abort 52 Log w TAG Incorrect URL url 53 catch Exception e 54 getRequest abort 55 Log w TAG Error whileretrieving bitmap from url e 56 finally 57 if client null 58 client close 59 60 61 return null 62 这是两种做法 还有一些应用在下载的时候使用了线程池和消息队列 MQ 对于 图片下载的效率要更好一些 有兴趣的同学可以看下 总结 对于远程图片等相对比较大的资源一定要在异步线程中去获取本地做缓存 责任编辑 立方 TEL 010 68476606 目前很多商业应用都会涉及到从网络上读取图片数据的问题 为了节约用户流量 应用一般会将图片缓存 起来 图片缓存一般分为内存缓存和外存缓存 内存 缓存运用 java 的缓存机制 在程序完全退出后 缓 存所在的内存空间可能被其它应用程序占用从而丢失 外存缓存一般放在程序特有的访问空间或者 sd 卡 中 在 sd 卡中存放的资源为公有资源 其它程序也可以访问 且对用户来讲没有一个强制清除缓存的规 范机制 综合以上 本文采用将缓存图片放置在程序的特有空间 中 其它应用程序无法访问 且用户可 以在应用程序管理中的 清除数据 选项中清除缓存 本文提供三种缓存策略 1 LRU 算法 固定缓存图片数量 max num 当图片数量超出 max num 时 将缓存中最近用的最少的图片删除 2 FTU 算法 固定每张图片的缓存时限 以最后一次使用 算起 超过时限后删除 3 FMU 算法 在存储器中固定一定大小的存储空间 超过固定空间后 将缓 存中占用最大尺寸的图片删除 使用时只需要向方法体中传递图片的 URL 即可 使用方法 1 导入 jar 2 获取服务 3 提交 url 交给程序去判断是否下载 public class ImagecachetacticsdemoActivity extends Activity public void onCreate Bundle savedInstanceState super onCreate savedInstanceState setContentView R layout item FMU imageCacheManager ImageCacheManager getImageCacheService this ImageCacheManager MODE FIXED MEMORY USED memory imageCacheManager setMax Memory 1024 1024 FTU imageCacheManager ImageCacheManager getImageCacheService this ImageCacheManager MODE FIXED TIMED USED time imageCacheManager setDelay millisecond 3 60 1000 LRU imageCacheManager ImageCacheManager getImageCacheService this ImageCacheManager MODE LEAST RECENTLY USED num imageCacheManager setMax num 5 imageCacheManager ImageCacheManager getImageCacheService this ImageCacheManager MODE NO CACHE USED nocache mImageView ImageView findViewById R id imageView new DownloadTask execute 417112640 2 jpg private class DownloadTask extends AsyncTask Override protected Bitmap doInBackground String params try return imageCacheManager downlaodImage new URL params 0 catch IOException e e printStackTrace return null Override protected void onPostExecute Bitmap result mImageView setImageBitmap result super onPostExecute result Override protected void onPreExecute mImageView setImageResource R drawable ic launcher super onPreExecute private ImageView mImageView private ImageCacheManager imageCacheManager 最近开发电视版的云存储应用 要求 我的相册 模块有全屏预览图片的功能 全屏分辨率 是 1920 1080 超清 UI 组件方面采用 Gallery ImageSwitcher 组合 这里略过 详情参见 google Android API 相册图片预取缓存策略是内存缓存 硬引用 LruCache 软引用 SoftReference 外部文件缓存 context getCachedDir 缓存中取不到的情况下再向服务端请求下载图 片 同时缓存三张图片 当前预览的这张 前一张以及后一张 1 内存缓存内存缓存 html view plaincopyprint 1 需要导入外部 jar 文件 android support v4 jar 2 import android support v4 util LruCache 3 开辟 8M 硬缓存空间 4 private final int hardCachedSize 8 1024 1024 5 hard cache 6 private final LruCache sHardBitmapCache new LruCache hardCachedSize 7 Override 8 public int sizeOf String key Bitmap value 9 return value getRowBytes value getHeight 10 11 Override 12 protected void entryRemoved boolean evicted String key Bitmap oldValue Bitmap newValue 13 Log v tag hard cache is full push to soft cache 14 硬引用缓存区满 将一个最不经常使用的 oldvalue 推入到软引用缓存区 15 sSoftBitmapCahe put key new SoftReference oldValue 16 17 18 软引用 19 private static final int SOFT CACHE CAPACITY 40 20 private final static LinkedHashMap String SoftReference sSoftBitmapCache 21 new LinkedHashMao String SoftReference SOFT CACHE CAPACITY 0 75f true 22 Override 23 public SoftReference put String key SoftReference value 24 return super input key value 25 26 Override 27 protected boolean removeEldestEntry LinkedHashMap Entry Stirng SoftReference eldest 28 if size SOFT CACHE CAPACITY 29 Log v tag Soft Reference limit purge one 30 return true 31 32 return false 33 34 35 缓存 bitmap 36 public boolean putBitmap String key Bitmap bitmap 37 if bitmap null 38 synchronized sHardBitmapCache 39 sHardBitmapCache put key bitmap 40 41 return true 42 43 return false 44 45 从缓存中获取 bitmap 46 public Bitmap getBitmap String key 47 synchronized sHardBitmapCache 48 final Bitmap bitmap sHardBitmapCache get key 49 if bitmap null 50 return bitmap 51 52 硬引用缓存区间中读取失败 从软引用缓存区间读取 53 synchronized sSoftBitmapCache 54 SoftReference bitmapReference sSoftBtimapCache get key 55 if bitmapReference null 56 final Bitmap bitmap2 bitmapReference get 57 if bitmap2 null 58 return bitmap2 59 else 60 Log v tag soft reference 已经被回收 61 sSoftBitmapCache remove key 62 63 64 65 return null 66 需要导入外部jar文件 android su import android support 开辟8M硬缓存空间 private final int hardC hard cache private final LruCache 2 外部文件缓存外部文件缓存 html view plaincopyprint 1 private File mCacheDir context getCacheDir 2 private static final int MAX CACHE SIZE 20 1024 1024 20M 3 private final LruCache sFileCache new LruCache MAX CACHE SIZE 4 Override 5 public int sizeOf String key Long value 6 return value intValue 7 8 Override 9 protected void entryRemoved boolean evicted String key Long oldValue Long newValue 10 File file getFile key 11 if file null 12 file delete 13 14 15 private File getFile String fileName throws FileNotFoundException 16 File file new File mCacheDir fileName 17 if file exists file isFile 18 throw new FileNotFoundException 文件不存在或有同名文件夹 19 return file 20 21 缓存 bitmap 到外部存储 22 public boolean putBitmap String key Bitmap bitmap 23 File file getFile key 24 if file null 25 Log v tag 文件已经存在 26 return true 27 28 FileOutputStream fos getOutputStream key 29 boolean saved press CompressFormat JPEG 100 fos 30 fos flush 31 fos close 32 if saved 33 synchronized sFileCache 34 sFileCache put key getFile key l
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 海南省陵水黎族自治县2025年上半年公开招聘城市协管员试题含答案分析
- 2025年二手房交易佣金支付标准协议
- 2025年度高科技企业采购法务与合同管理综合服务合同
- 2025房地产无底薪业务员营销服务及佣金分配合同
- 2025年度大型活动专用场馆租赁服务合同
- 2025年医疗设备采购与售后服务合同
- 2025版商铺租赁委托与市场拓展合作合同
- 2025年出租车行业新能源技术研发合作协议
- 2025版建筑废弃物填土处理工程合同
- 2025年度图书出版翻译与校对服务合同
- 2025-2026秋季中小学第一学期升旗仪式22周校长演讲稿:第1周 烽火记忆照前路秋风为序启新程
- 2025年山东省菏泽市中考英语真题(无答案)
- 2025劳动合同书示范文本下载
- 急性阑尾炎病人护理课件
- 水利水电工程单元工程施工质量验收标准第8部分:安全监测工程
- 2026年高考政治一轮复习:高考政治主观题背诵提纲汇编
- 2025年高考山东卷化学试题讲评及备考策略指导(课件)
- 2022森林防火道路建设基本要求
- 寻找消失的滇缅路:松山战痕课件
- 部编人教版《道德与法治》九年级上册教材介绍课件
- 政府预算理论与实务(第四版)全套教学课件
评论
0/150
提交评论