http://www.cctime.com/html/2011-11-29/201111291037553094_2.htm

http://blog.csdn.net/life02/article/details/7588502

在下载文件或者在线浏览文件时,或者为了保证文件下载的正确性,需要使用缓存机制,常使用SoftReference来实现。

SoftReference的特点是它的一个实例保存对一个Java对象的软引用,该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对这个Java对象回收前,SoftReference类所提供的get方法返回Java对象的强引用。另外,一旦垃圾线程回收该Java对象之后,get方法将返回null。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

一般的缓存策略是:

一级内存缓存、二级文件缓存(数据库也算作文件缓存)、三级网络数据

一、网络下载的缓存策略

关于网络下载文件(图片、音频、视频)的基本策略:

1.不要直接下载到目标文件,应使用temp文件作中转,以确保文件的正确性与完整性,流程如下:

a)以网络目标文件名 A 生成唯一的本地目标文件名 B

b)以本地目标文件名 B 生成唯一的本地临时文件名 T

c)下载文件到 T 中

d)下载完毕,校验文件 T 的正确性与完整性

e)若不正确或不完整则 delete 文件 T,并返回 false

f)校验完毕后,将文件 T 重命名 或 复制到 B 文件

g)最后的清理现场,删除临时文件 T,成功后,返回 true

2.尽力提供文件正确性与完整性的校验:

a)正确性:比如 MD5/Hash Code 比对、文件格式的比对。

b)完整性:比如 文件大小是否一致、图片的数据是否正确(图片文件头中提供了相关信息)

3.考虑对于下载到本地的文件是否需要再做二次加工,可以思考以下情况:

a)比如网络源始图片的大小为800*600,而我们需要作为缩略图的大小为160*145,所以考虑对下载后的文件进行裁剪,再保存,对于源始文件则直接删除。

二、文件缓存策略:

1.需要唯一的缓存文件的对应I/O key,一般可以使用 hashcode。

2.若是同一个文件,以不同的时间,可以考虑,先清本地缓存,再下载新的缓存到本地。

3.同一文件也可以加上时间戳后,再生成唯一hashcode。

4.生成文件缓时,也许需要作以下全面的考虑:

a)sdcard是否已经没有空间(这个需求是存在的,但几乎没有人会考虑到,一旦发生,必crash)。

b)缓存的清理策略。每日、每周定时清理?到达一个阀值后,自动清理?(若无清理策略,把垃圾数据一直当个宝一相存着,是很SB的)。

c)缓存真正需要的数据。不要觉外存是无限的,所以就可以什么都存,要知道,多则繁,繁则乱。曾经有一同事,每天存几百MB的用户数据(所有用户的性别、 age、联系方式等等),而PM需要的只是一个每日数户的活跃数据报表,于是最后改为缓存每天的用户分析报表数据即可(才10几KB)。

d)给缓存文件加密。最简单就是去掉文件的扩展名,这也算加密,当然,你可以把服务端文件加密,然后在内存中解密。这就看项目的需求而定,我的经验也不足,一般就是改改扩展名之类的。

网络图片在开发过程中,一般都将图片缓存到本地sd卡中(经常要使用的图片),方便下次直接引用而不再次请求网络耗费资源。而如果是自己开发搜索功能里有涉及到图片的显示,可以直接Map<String, SoftReference<Drawable>>,即软引用。软引用重要代码代码:package com.test.load; import java.lang.ref.SoftReference;import java.net.URL;import java.util.HashMap;import java.util.Map; import android.graphics.drawable.Drawable;import android.os.Handler;import android.os.Message; public class ThreadImgLoader {  private Map<String, SoftReference<Drawable>> imageCache=new HashMap<String, SoftReference<Drawable>>();     public Drawable loadDrawable(final String imgUrl, final ImageCallback callback){      if (imageCache.containsKey(imgUrl)) {        SoftReference<Drawable> sf=imageCache.get(imgUrl);        if (sf.get()!=null) {           return sf.get();        }      }      final Handler handler=new Handler(){        public void handleMessage(Message msg) {           callback.imageLoaded((Drawable) msg.obj);        }      };      new Thread(){        public void run() {           Drawable drawable=loadImgFromUrl(imgUrl);           if (drawable!=null) {              imageCache.put(imgUrl, new SoftReference<Drawable>(drawable));              Message msg=handler.obtainMessage(0, drawable);              handler.sendMessage(msg);           }        }      }.start();      return null;   }     public Drawable loadImgFromUrl(String imgUrl) {      try {        return Drawable.createFromStream(new URL(imgUrl).openStream(), "src");      } catch (Exception e) {        return null;      }   }     public interface ImageCallback{      public void imageLoaded(Drawable drawable);   }} 下面是缓存到SD卡的重要代码,当然你也可以搜索一下,这方面的东西很多。WeakHashMap也是使用了软引用,你可以去看它的源代码:package com.test; import java.io.File;import java.io.FileOutputStream;import java.io.OutputStream;import java.util.WeakHashMap; import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;import android.os.Environment; public class MyImgCache extends WeakHashMap<String, Bitmap> {   private static MyImgCache myImgCache=new MyImgCache();   private static final String CACHE_FILE="/MyXiaoCaiImg";   public static MyImgCache getInstance(){      return myImgCache;   }     public boolean isBitmapExist(String url) {      boolean isexist=false;      String name=changeUrlName(url);      String filePath=isMakeFile();      File file=new File(filePath, name);      if (containsKey(url)) {        isexist=true;      }else if (file.exists()) {        String path=file.getAbsolutePath();        System.out.println(path);        Bitmap bitmap=BitmapFactory.decodeFile(path);        if (bitmap!=null) {           put(url, bitmap, false);           isexist=true;        }      }      return isexist;   }    private String changeUrlName(String url) {      String name = url.replaceAll(":", "_");      name = name.replaceAll("//", "_");      name = name.replaceAll("/", "_");      name = name.replaceAll("=", "_");      name = name.replaceAll(",", "_");      name = name.replaceAll("&", "_");      return name;   }     private String isMakeFile() {      String rootpath = null;      if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {        rootpath = Environment.getExternalStorageDirectory().toString();      }      String filepath = rootpath + CACHE_FILE;      File file = new File(filepath);      if (!file.exists()) {        file.mkdirs();      }      return filepath;   }    public Bitmap put(String key, Bitmap value) {      String name=changeUrlName(key);      String filePath=isMakeFile();      File file = new File(filePath, name);      OutputStream outputStream = null;      try {        outputStream = new FileOutputStream(file);        value.compress(CompressFormat.JPEG, 100, outputStream);        outputStream.flush();        outputStream.close();        outputStream = null;      } catch (Exception e) {        e.printStackTrace();      }      return super.put(key, value);   }    public Bitmap put(String key, Bitmap value, boolean b) {      if (b) {        return this.put(key, value);      }else {        return super.put(key, value);      }   } }

更多相关文章

  1. [Android(安卓)Training视频系列]6.1 Saving Key-Value Sets
  2. Android不混淆第三方jar包
  3. android:快速搜索手机中文件
  4. 手机安全卫士开发系列(7)——知识点整理(1)
  5. Android(安卓)SDK无法更新
  6. Android(安卓)ImageLoader 本地缓存
  7. Android之MTP框架和流程分析
  8. 怎样在Android中解析doc、docx、xls、xlsx格式文
  9. android反编译工具 ApkDec-Release-0.1

随机推荐

  1. Elasticsearch—用logstash增量导入Mysql
  2. spark与kafka集成
  3. 一文读懂 TS 中 Object, object, {} 类型
  4. Kafka Consumer消费能力较低时的解决方案
  5. 实力解剖一枚挖矿脚本,风骚操作亮瞎双眼
  6. BTree索引/Hash索引
  7. 如何让 linux 包转发达到 40万pps,尝试中
  8. OceanBase、X-DB、POLARDB 分布式关系型
  9. Netfliter状态跟踪之动态协议的实现浅析(t
  10. PolarDB和Aurora区别