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

 
对于客户端——服务器端应用,从远程获取图片算是经常要用的一个功能,而图片资源往往会消耗比较大的流量,对应用来说,如果处理不好这个问题,那会让用户很崩溃,不知不觉手机流量就用完了,等用户发现是你的应用消耗掉了他手机流量的话,那么可想而知你的应用将面临什么样的命运。
 
另外一个问题就是加载速度,如果应用中图片加载速度很慢的话,那么用户同样会等到崩溃。
那么如何处理好图片资源的获取和管理呢?
异步下载
本地缓存
异步下载
大家都知道,在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卡上
  • private void saveBmpToSd(Bitmap bm, Stringurl) {
  •         if (bm == null) {
  •             Log.w(TAG, " trying to savenull bitmap");
  •             return;
  •         }
  •          //判断sdcard上的空间
  •         if (FREE_SD_SPACE_NEEDED_TO_CACHE >freeSpaceOnSd()) {
  •             Log.w(TAG, "Low free space onsd, do not cache");
  •             return;
  •         }
  •         String filename =convertUrlToFileName(url);
  •         String dir = getDirectory(filename);
  •         File file = new File(dir +"/" + filename);
  •         try {
  •             file.createNewFile();
  •             OutputStream outStream = newFileOutputStream(file);
  •            bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
  •             outStream.flush();
  •             outStream.close();
  •             Log.i(TAG, "Image saved tosd");
  •         } catch (FileNotFoundException e) {
  •             Log.w(TAG,"FileNotFoundException");
  •         } catch (IOException e) {
  •             Log.w(TAG,"IOException");
  •         }
  •     }
计算sdcard上的空间:
  • /**
  • * 计算sdcard上的剩余空间
  • *@return
  • */
  • private int freeSpaceOnSd() {
  •     StatFs stat = newStatFs(Environment.getExternalStorageDirectory() .getPath());
  •     double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;
  •     return (int) sdFreeMB;
  • }
修改文件的最后修改时间
  • /**
  • * 修改文件的最后修改时间
  • * @param dir
  • * @param fileName
  • */
  • private void updateFileTime(String dir,String fileName) {
  •     File file = new File(dir,fileName);        
  •     long newModifiedTime =System.currentTimeMillis();
  •     file.setLastModified(newModifiedTime);
  • }
本地缓存优化
  • /**
  • *计算存储目录下的文件大小,当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定
  • * 那么删除40%最近没有被使用的文件
  • * @param dirPath
  • * @param filename
  • */
  • private void removeCache(String dirPath) {
  •     File dir = new File(dirPath);
  •     File[] files = dir.listFiles();
  •     if (files == null) {
  •         return;
  •     }
  •     int dirSize = 0;
  •     for (int i = 0; i < files.length;i++) {
  •         if(files.getName().contains(WHOLESALE_CONV)) {
  •             dirSize += files.length();
  •         }
  •     }
  •     if (dirSize > CACHE_SIZE * MB ||FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
  •         int removeFactor = (int) ((0.4 *files.length) + 1);
  •         Arrays.sort(files, newFileLastModifSort());
  •         Log.i(TAG, "Clear some expiredcache files ");
  •         for (int i = 0; i <removeFactor; i++) {
  •             if(files.getName().contains(WHOLESALE_CONV)) {
  •                 files.delete();              
  •             }
  •         }
  •     }
  • }
  • /**
  • * 删除过期文件
  • * @param dirPath
  • * @param filename
  • */
  • private void removeExpiredCache(StringdirPath, String filename) {
  •     File file = new File(dirPath,filename);
  •     if (System.currentTimeMillis() -file.lastModified() > mTimeDiff) {
  •         Log.i(TAG, "Clear some expiredcache files ");
  •         file.delete();
  •     }
  • }
文件使用时间排序
  • /**
  • * TODO 根据文件的最后修改时间进行排序 *
  • */
  • classFileLastModifSort implements Comparator<File>{
  •     public int compare(File arg0, File arg1) {
  •         if (arg0.lastModified() >arg1.lastModified()) {
  •             return 1;
  •         } else if (arg0.lastModified() ==arg1.lastModified()) {
  •             return 0;
  •         } else {
  •             return -1;
  •         }
  •     }
  • }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值