`

Android 利用缓存机制实现文件下载

 
阅读更多

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);

      }

   }

 

}

 

分享到:
评论

相关推荐

    Android使用缓存机制实现文件下载及异步请求图片加三级缓存

    总的来说,Android的缓存机制在文件下载和图片请求中起到了关键作用,通过合理利用内存、文件和网络资源,优化了数据加载速度,提高了用户体验,同时也有效地管理了设备的存储空间。开发者在实现这些功能时,需要...

    Android双缓存机制

    在Android开发中,为了优化用户体验,特别是在处理大量数据如ListView或GridView时,通常会采用双缓存机制来解决图片加载的问题。这种机制主要是为了解决因网络延迟或内存不足导致的图片加载慢或者闪退等问题。双...

    android缓存机制分析.docx

    Android缓存机制是为了提高应用程序性能和用户体验而设计的一种存储策略。缓存允许应用程序快速访问最近或频繁使用的数据,避免每次需要时都重新从网络、磁盘或其他慢速源加载。在Android系统中,缓存主要应用于图片...

    android 离线下载实现版本更新,图片缓存

    同时,利用缓存机制,当图片已经缓存时,直接从缓存中读取,避免重复下载。 4. **版本更新与缓存管理**: 在版本更新时,需要清理旧的资源缓存,以避免使用过期数据。可以设置缓存文件的生命周期,或者在启动应用时...

    android缓存技术之文件缓存

    在实际应用中,为了实现高效且健壮的缓存机制,还需要考虑以下几点: - **缓存策略**:包括LRU(Least Recently Used)、FIFO(First In First Out)等,决定何时删除旧的缓存文件。LRU策略通常更受欢迎,因为它...

    Android文件缓存与内存缓存

    本文将深入探讨这两种缓存机制,以及如何解决图片错位问题。 首先,我们来了解什么是双缓存策略。双缓存是指同时使用内存缓存和文件缓存,以达到快速访问数据的目的。内存缓存具有高速读写的优势,但存储空间有限;...

    Android例子源码异步批量下载图片并缓存

    实现这个功能,我们可以使用第三方库,如 Glide、Picasso 或 Fresco,它们都内置了高效的图片加载和缓存机制。以Glide为例,它的基本使用步骤如下: 1. 添加Glide依赖:在`build.gradle`文件中引入Glide库。 2. ...

    Android WebView 实现缓存网页数据

    在Android开发中,`WebView` 是一个非常重要的组件,它允许开发者在应用程序内嵌入一个浏览器,用于显示网页内容。...同时,理解和掌握 `WebView` 缓存机制也有助于优化应用程序的性能和资源利用。

    Android 数据缓存工具类

    在Android中,常见的缓存机制有内存缓存和磁盘缓存。内存缓存(如LruCache)利用系统的内存空间,访问速度快但数据易丢失;磁盘缓存(如SQLite、SharedPreferences或文件系统)则能持久保存数据,但读写速度相对较慢...

    自己实现的Android 三级缓存图片加载框架

    3. **多线程加载**:利用Android的Loader机制或者自定义线程池实现图片的异步加载,避免UI阻塞。同时,可能采用了线程同步机制,如锁或者信号量,以防止多个线程同时访问同一资源导致的数据冲突。 4. **图片解码**...

    android图片缓存有关的项目

    - 内存缓存(Memory Cache):利用Android系统的内存,缓存近期或常用图片,访问速度快,但容量有限。 - 磁盘缓存(Disk Cache):使用设备的磁盘空间存储图片,容量较大但访问速度相对较慢。当内存缓存不足时,会...

    android利用http协议把网页内容下载到指定文件夹

    在Android平台上,将网页内容通过HTTP协议下载到指定文件夹是一项常见的任务,尤其在离线浏览、数据缓存或者后台更新资源的场景中。HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议,它允许客户端(如...

    从源代码分析Android Universal ImageLoader的缓存处理机制

    总的来说,Android Universal ImageLoader通过高效的缓存机制,确保了图片加载的性能和响应速度,同时也提供了灵活的配置选项,以适应不同应用的需求。通过深入理解其缓存处理机制,开发者可以更好地优化图片加载...

    Android缓存方案

    1. 磁盘缓存:Android提供了HttpUrlConnection和OkHttp等网络库,它们内置了磁盘缓存机制。通过设置缓存大小和路径,网络请求的响应数据会被自动存储到指定目录下,下次请求相同资源时,可以直接从磁盘读取,避免了...

    Android批量下载图片并缓存,非常流畅

    首先,我们需要理解Android中的图片缓存机制。在Android系统中,内存缓存和磁盘缓存是常用的两种缓存方式。内存缓存,即LruCache,用于存储最近使用(Least Recently Used)的数据,当内存不足时,会自动清理最少...

    Android图片下载三级缓存策略源码Demo

    "Android图片下载三级缓存策略源码Demo" 提供了一种解决方案,它利用了LruCache、软引用以及DiskLruCache来实现三级缓存机制。这种策略能够有效地减少网络请求,提高图片加载速度,同时节省设备资源。现在,让我们...

    Android API中文帮助文档合集

    还有WebSocket用于实时双向通信,以及Android的Intent机制实现服务间的通信。此外,Retrofit和AsyncTask等库简化了异步任务处理。 五、多媒体处理 Android SDK提供了MediaStore接口访问设备上的音频、视频和图片,...

    Android WebView cache 缓存 在线 视频播放

    总结,Android WebView的缓存机制对于优化在线视频播放和实现离线阅读至关重要。开发者需要理解WebView的缓存策略,合理配置缓存路径,以及利用WebViewClient和WebSettings的方法来控制缓存行为。通过这些技巧,我们...

    android开发 文件上传下载 源码

    2. Android Volley:Volley是Google推荐的网络库,提供了异步请求处理和缓存机制,可以方便地处理文件上传。 3. Retrofit:Retrofit是一个现代的HTTP客户端库,结合Gson或其它转换库,可以方便地构建上传API接口。 4...

    Android的内存机制和溢出说明

    性能调优还包括避免一次性加载过多数据,使用列表视图(ListView)和滚动视图(RecyclerView)的缓存机制,以及合理使用软引用(SoftReference)和弱引用。此外,使用Android的最新版本和优化过的ART虚拟机可以...

Global site tag (gtag.js) - Google Analytics