用AsyncTask实现了异步下载图片了,现在想实现个缓存,想把图片下载到sd卡上,然后每次要下载图片时都检查看sd卡,如果有直接从sd卡上读取出来,没有再去下载并下载后存到sd卡上,有没有大神有代码可以学习下的?

解决方案 »

  1.   

    能存进去,那大牛你告诉我下,知道文件的具体路径和文件名称,怎么把它从sd卡里取出然后转化成bitmap流呢?求指导~
      

  2.   

    这代码网上也应该有的吧,一段给你参考下File file = new File(Environment.getExternalStorageDirectory()+"/device.png");
    InputStream inputStream = new FileInputStream(file);
    long length = file.length();
            byte[] bytes = new byte[(int)length];
            int offset = 0;
            int numRead = 0;
            while (offset < bytes.length && (numRead= inputStream.read(bytes, offset, bytes.length-offset)) >= 0) 
            {
                offset += numRead;
            }
           Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);  
      

  3.   

    思路就是这样的
    你需要有个配合记录的文件,比如数据库,我们的项目里是这么干的
    下载图片获取Bitmap,将bitmap写到sd卡,同时将图片sd卡保存的路径和图片对应的网络url做为一条记录存起。
    读取图片的时候,优先通过数据库获取url对应的本地路径的图片,没在本地取到bitmap,再去网络获取至于具体实现,楼主还是自己来吧,没什么难度
      

  4.   

    如果是本地图片的话应该很简单的吧,能拿到uri就很容易转bitmap的。BitmapFactory.decodeStream(is).is就是一个输入流。怎么做IO你到你具体的图片应该还是挺简单的吧。PS:我也是个新手,以上是些浅薄的建议望笑纳。
      

  5.   

    我刚做这个功能,哈哈,其实你第一次下载下来缓存的时候可以定义个全局图片存储的sdcard路径,这样,判断图片存不存在就用之前定义的路径,这样就ok了呀
      

  6.   

    我对图片出来的类:
    package com.mandao.animal1.util;import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.List;import android.graphics.Bitmap;
    import android.os.Environment;
    import android.os.StatFs;
    import android.util.Log;import com.mandao.animal1.common.Config;/**
     * 将图片存到sdcard中。
     * @author xiaomiao
     *
     */
    public class SaveImageToSdcard {
    private final String TAG = this.getClass().toString();
    private int imageLength;
    public final int CACHE_SIZE = 20; //设置保存图片文件夹为20M
    public final static int MB = 1024 * 1024;
    public final int OVER_TIME = 14 * 24 * 60 * 60 * 1000; //过期时间总数是两个星期
    public final String WHOLESALE_CONV = ".png";
    /**
     * 构造函数传递图片大小
     * @param imgLength
     */
    public SaveImageToSdcard(int imgLength){
    this.imageLength = imgLength;
    }
    /**
     * 图片保存
     * @param 图片
     * @param 保存路径地址
     */
    public void saveBmpToSd(Bitmap bm, String url,int chapter, String bookName) {       
    if (bm == null) {
    Log.w(TAG, " trying to save null bitmap");
    return;
    }
    // 判断sdcard上的空间
    if (imageLength > freeSpaceOnSd()) {
    Log.w(TAG, "Low free space onsd, do not cache");
    return;
    }
    //截取图片名称的后面名字
    String filename = convertUrlToFileName(url);
    try {
    File file = new File(Config.FILEDIR);
    if(!file.exists()){
    file.mkdir();
    }
    //创建一个目录
    file = new File(Config.FILEDIR + File.separator + bookName);
    if(!file.exists()){
    file.mkdir();
    }
    //当chapter为0时表示图片为封面,保存在漫画目录下
    if(chapter == 0){
    file = new File(Config.FILEDIR + File.separator + bookName, filename);
    }else{
    //创建章节目录
    file = new File(Config.FILEDIR + File.separator + bookName + File.separator + chapter);
    if(!file.exists()){
    file.mkdir();
    }
    //在目录下创建图片文件
    file = new File(Config.FILEDIR + File.separator + bookName + File.separator + chapter, filename);
    }

    // //先删除两个星期没用过的图片
    // removeExpiredCache(FILEDIR + File.separator + bookName);
    // //要是还是不够大,删除近期没用过的图片
    // removeCache(FILEDIR + File.separator + bookName);

    if (!file.exists()) {
    file.createNewFile();
    }
    OutputStream outStream = new FileOutputStream(file);
    bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
    outStream.flush();
    outStream.close();
    Log.i(TAG, "Image saved");
    } catch (FileNotFoundException e) {
    Log.w(TAG, "FileNotFoundException");
    } catch (IOException e) {
    Log.w(TAG, "IOException");
    }
    } /** 
     * 计算sdcard上的剩余空间 
     * @return 
     */
    private int freeSpaceOnSd() {
    boolean sdCardExit = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
    //判断sdcard是否存在
    if(sdCardExit) {
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
    .getPath());
    double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat
    .getBlockSize()) / MB;
    return (int) sdFreeMB;
    }else {
    Log.i(TAG, "sdCard is not exist");
    return 0;
    }
    }
    /**  
     * 修改文件的最后修改时间 
     * @param 文件目录  
     * @param 文件名称 
     */ 
    private void updateFileTime(String dir,String fileName) {    
    File file = new File(dir,fileName);          
    long newModifiedTime = System.currentTimeMillis();    
    file.setLastModified(newModifiedTime); 

    /**
     * 从图片路径中获取图片名
     * @param url
     */
    private String convertUrlToFileName(String url){
    String name = "";
    if(url != null && !"".equals(url)){
    name = url.substring(url.lastIndexOf("/")+1, url.length());
    }
    return name;
    }
    /** 
     *计算存储目录下的文件大小,当文件总大小大于规定的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[i].getName().toLowerCase().contains(WHOLESALE_CONV)) {             
    dirSize += files[i].length();       
    }    
    }    
    if (dirSize > CACHE_SIZE * MB || imageLength > freeSpaceOnSd()) {        
    int removeFactor = (int) ((0.4 * files.length) + 1);         
    Arrays.sort(files, new FileLastModifSort());          
    Log.i(TAG, "Clear some expiredcache files ");         
    for (int i = 0; i < removeFactor; i++) {              
    if(files[i].getName().toLowerCase().contains(WHOLESALE_CONV)) {              
    files[i].delete();                          
    }         
    }   
    }
    }
    /**  
     * 删除过期文件  
     * @param dirPath  
     * @param filename  
     */ 
    public void removeExpiredCache(String dirPath) { 
    List<String> listImage = GetSdcardImageList.getIamgeName(dirPath);
    //循环将过期的图片删除
    if(listImage != null){
    for(int i=0;i<listImage.size();i++){
    File file = new File(dirPath,listImage.get(i));  
    if (System.currentTimeMillis() - file.lastModified() > OVER_TIME) {         
    Log.i(TAG, "Clear some expiredcache files");         
    file.delete();     

    }
    }
    }
    /**  
     * TODO 根据文件的最后修改时间进行排序 *  
     */ 
    class FileLastModifSort 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;
    }
    }
    }
        /**
         * 删除图片目录
         * @param url
         */
        public static void deleteDir(String url){
         File f = new File(url);
         if(f.isDirectory()){
         f.delete();
         }
        }
    }