android文件缓存策略,Android 文件缓存方法

前言

我们经常遇到从网络获取图片,为了使图片查看流畅,我们肯定要使用缓存,大部分我们会使用内存缓存,但是android内存缓存毕竟是有限的,这样的话,我们必须使用文件来缓存部分图片。

思路

当我们把一张图片从网络下载成功以后,这个图片会被加入内存缓存和文件缓存,内存缓存来说请参考Android内存溢出大总结,对于文件缓存来说,这张图片将被以url的哈希值加cach后缀名的形式存储在SD卡上,这样,当下一次再需要同一个url的图片的时候,就不需要从网络下载了,而是直接通过url来进行查找。同时一张图片被访问时,它的最后修改时间将被更新,这样的意义在于:当SD卡空间不足的时候,将会按照最后修改时间来删除40%缓存的图片,确切来说,那些修改时间比较早的图片将会被删除。

代码

package com.ty.highway.highwaysystem.support.utils.cache;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.Environment;

import android.os.StatFs;

import android.util.Log;

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;

/**

* Created by fuweiwei on 2016/1/26.

* 文件缓存

* 内存缓存是有限的,其它的文件缓存,当文件缓存操作一定量时我们删除之前的缓存

*/

public class ImageFileCache

{

private static final String TAG = "ImageFileCache";

//图片缓存目录

private static final String IMGCACHDIR = "/sdcard/ImgCach";

//保存的cache文件宽展名

private static final String CACHETAIL = ".cach";

private static final int MB = 1024*1024;

private static final int CACHE_SIZE = 1;

//当SD卡剩余空间小于10M的时候会清理缓存

private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10;

public ImageFileCache()

{

//清理部分文件缓存

removeCache(IMGCACHDIR);

}

/**

* 从缓存中获取图片

*/

public Bitmap getImageFromFile(final String url)

{

final String path = IMGCACHDIR + "/" + convertUrlToFileName(url);

File file = new File(path);

if (file != null && file.exists())

{

Bitmap bmp = BitmapFactory.decodeFile(path);

if (bmp == null)

{

file.delete();

}

else

{

updateFileTime(path);

Log.d(TAG, "get bmp from FileCache,url=" + url);

return bmp;

}

}

return null;

}

/**

* 将图片存入文件缓存

*/

public void saveBitmapToFile(Bitmap bm, String url)

{

if (bm == null) {

return;

}

//判断sdcard上的空间

if (FREE_SD_SPACE_NEEDED_TO_CACHE > SdCardFreeSpace())

{

//SD空间不足

return;

}

String filename = convertUrlToFileName(url);

File dirFile = new File(IMGCACHDIR);

if (!dirFile.exists())

dirFile.mkdirs();

File file = new File(IMGCACHDIR +"/" + filename);

try

{

file.createNewFile();

OutputStream outStream = new FileOutputStream(file);

bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);

outStream.flush();

outStream.close();

}

catch (FileNotFoundException e)

{

Log.d(TAG, "FileNotFoundException");

}

catch (IOException e)

{

Log.d(TAG, "IOException");

}

}

/**

* 计算存储目录下的文件大小,

* 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定

* 那么删除40%最近没有被使用的文件

*/

private boolean removeCache(String dirPath)

{

File dir = new File(dirPath);

File[] files = dir.listFiles();

if (files == null)

{

return true;

}

if (!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))

{

return false;

}

int dirSize = 0;

for (int i = 0; i < files.length; i++)

{

if (files[i].getName().contains(CACHETAIL))

{

dirSize += files[i].length();

}

}

if (dirSize > CACHE_SIZE * MB || FREE_SD_SPACE_NEEDED_TO_CACHE > SdCardFreeSpace())

{

int removeFactor = (int) (0.4 * files.length);

Arrays.sort(files, new FileLastModifSort());

for (int i = 0; i < removeFactor; i++)

{

if (files[i].getName().contains(CACHETAIL))

{

files[i].delete();

}

}

}

if (SdCardFreeSpace() <= CACHE_SIZE)

{

return false;

}

return true;

}

/**

* 修改文件的最后修改时间

*/

public void updateFileTime(String path)

{

File file = new File(path);

long newModifiedTime = System.currentTimeMillis();

file.setLastModified(newModifiedTime);

}

/**

* 计算SD卡上的剩余空间

*/

private int SdCardFreeSpace()

{

StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());

double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;

return (int) sdFreeMB;

}

/**

* 将url转成文件名

*/

private String convertUrlToFileName(String url)

{

return url.hashCode() + CACHETAIL;

}

/**

* 根据文件的最后修改时间进行排序

*/

private class FileLastModifSort implements Comparator{

public int compare(File file0, File file1)

{

if (file0.lastModified() > file1.lastModified())

{

return 1;

}

else if (file0.lastModified() == file1.lastModified())

{

return 0;

}

else

{

return -1;

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值