关于缓存图片到sd卡里的
用AsyncTask实现了异步下载图片了,现在想实现个缓存,想把图片下载到sd卡上,然后每次要下载图片时都检查看sd卡,如果有直接从sd卡上读取出来,没有再去下载并下载后存到sd卡上,有没有大神有代码可以学习下的?
[解决办法]
这代码网上也应该有的吧,一段给你参考下
- Java code
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);
[解决办法]
思路就是这样的
你需要有个配合记录的文件,比如数据库,我们的项目里是这么干的
下载图片获取Bitmap,将bitmap写到sd卡,同时将图片sd卡保存的路径和图片对应的网络url做为一条记录存起。
读取图片的时候,优先通过数据库获取url对应的本地路径的图片,没在本地取到bitmap,再去网络获取
至于具体实现,楼主还是自己来吧,没什么难度
[解决办法]
我对图片出来的类:
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();
}
}
}