android文件缓存,并SD卡创建目录未能解决和bitmap内存溢出解决

1.相关代码:

加入权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    /** 获取SD卡路径 **/
    private static String getSDPath() {
        String sdcardPath = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED);  //推断sd卡是否存在
        if (sdCardExist) {
            sdcardPath = Environment.getExternalStorageDirectory();//获取根文件夹
        }
        if (sdcardPath != null) {
            return sdcardPath;
        } else {
            return "";
        }
    }

解决方法:获取根文件夹的代码改为:

sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();

这样就能够了。

----------------------------------------------------------------------------------------------------------------------------------

附文件缓存类:

package com.etnet.utilities;

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 android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;

/**
 * 图片文件保存、读写类
 * @author Barry
 */
public class FileOperationUtil {
	private static final String TAG = "FileOperationUtil";
    private static final String CACHE_DIRECTORY = "TqProCache";

    private static final int MB = 1024*1024;
    private static final int MAX_CACHE_SIZE = 10 * MB;
    private static final int LEAST_SIZE_OF_SDCARD = 10 * MB;

    /** 从缓存中获取图片 **/
    public static Bitmap getImage(final String imageUrl) {
        final String path = getCacheDirectory() + "/" + convertUrlToFileName(imageUrl);
       // Log.i(TAG, "getImage filepath:" + path);
       // Log.i(TAG, "getImage url:" + url);
        File file = new File(path);
        if (file.exists()) {
//        	Log.i(TAG, "getImage file exists");
        	Bitmap bmp = null;
        	try {
        		//宽变为原图的1/3。高也变为原图的1/3。这样是为了减少内存的消耗,防止内存溢出
        		BitmapFactory.Options options=new BitmapFactory.Options();
        		options.inSampleSize = 3;
        		bmp = BitmapFactory.decodeFile(path,options);
        		LogUtil.d(TAG, "bmp size="+bmp.getByteCount());
			} catch (Exception e) {
				e.printStackTrace();
			}
            if (bmp == null) {
                file.delete();
            } else {
            	updateFileTime(path);
                return bmp;
            }
        }
        return null;
    }

    /** 将图片存入文件缓存 **/
    public static void saveBitmap(String imageUrl, Bitmap bm ) {
        if (bm == null) {
            return;
        }
        //推断sdcard上的空间
        if (getFreeSpaceOfSdcard() < LEAST_SIZE_OF_SDCARD) {
            //SD空间不足
            return;
        }
        String filename = convertUrlToFileName(imageUrl);
        String dir = getCacheDirectory();
        File dirFile = new File(dir);
        if (!dirFile.exists()){
        	if(!dirFile.mkdirs()){
        		Log.w(TAG, "create cache file directorys failed");
        	}
        }
        File file = new File(dir +"/" + filename);
        try {
            file.createNewFile();
            OutputStream outStream = new FileOutputStream(file);
            bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
            outStream.flush();
            outStream.close();
        } catch (FileNotFoundException e) {
            Log.w(TAG, "FileNotFoundException");
        } catch (IOException e) {
            Log.w(TAG, "IOException");
        }
    }

    /**
     * 计算存储文件夹下的文件大小,
     * 当文件总大小大于指定的MAX_CACHE_SIZE或者sdcard剩余空间小于指定的LEAST_SIZE_OF_SDCARD
     * 那么删除40%近期没有被使用的文件
     */
    public static boolean removeExtraCache() {
        File dir = new File(getCacheDirectory());
        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++) {
        	dirSize += files[i].length();
        }
//        LogUtil.d("Barry", "dirSize="+dirSize);

        if (dirSize > MAX_CACHE_SIZE || getFreeSpaceOfSdcard() < LEAST_SIZE_OF_SDCARD) {
            int removeNum = (int) ((0.4 * files.length) + 1);
            /* 依据文件的最后改动时间进行升序排序 */
            Arrays.sort(files, new Comparator<File>() {
            	@Override
            	 public int compare(File file1, File file2) {
                     if (file1.lastModified() > file2.lastModified()) {
                         return 1;
                     } else if (file1.lastModified() == file2.lastModified()) {
                         return 0;
                     } else {
                         return -1;
                     }
                 }
			});
           /* for (int i = 0; i < files.length; i++) {
            	LogUtil.d("Barry", "file.modifiedTime="+files[i].lastModified());
			}*/
            for (int i = 0; i < removeNum; i++) {
            	files[i].delete();
            }
            return true;
        }else{
        	return false;
        }
    }

    /** 改动文件的最后改动时间 **/
    public static void updateFileTime(String path) {
        File file = new File(path);
        long newModifiedTime = System.currentTimeMillis();
        file.setLastModified(newModifiedTime);
    }

    /** 计算sdcard上的剩余空间 **/
    private static int getFreeSpaceOfSdcard() {
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
        double sdFreeSize = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize());
        return (int) sdFreeSize;
    }

    private static String convertUrlToFileName(String url) {
        String[] strs = url.split("/");
        String savedImageName = strs[strs.length - 1];
        return savedImageName;
    }

    /** 获得缓存文件夹 **/
    private static String getCacheDirectory() {
        String dir = getSDPath() + "/" + CACHE_DIRECTORY;
        return dir;
    }

    /** 获取SD卡路径 **/
    private static String getSDPath() {
        String sdcardPath = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED);  //推断sd卡是否存在
        if (sdCardExist) {
            sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();  //获取根文件夹
        }
        if (sdcardPath != null) {
            return sdcardPath;
        } else {
            return "";
        }
    }
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-08-26 11:19:51

android文件缓存,并SD卡创建目录未能解决和bitmap内存溢出解决的相关文章

Android文件存储往SD卡中写入文件路径出错问题求解。

============问题描述============   因为学习需要  看的老罗的视频  关于数据存储往SD卡写文件的那一部分  几乎完全照办的敲的代码   结果在pad上测试的时候和预想的有区别     本来应该存储到SD卡中的文件结果跑到pad自带内存中去了...   然后我尝试过把路径直接自己手动写  还是一样存到了自带内存中  这到底是为什么啊? 顺带吐槽一下万恶的导师  十一还要我们加班 求大神们指导呀~   国庆节玩的开学哟!!! ============解决方案1======

android文件保存到sd卡和内存

1.保存到SD卡中: 获取SDCard的状态: Environment.getExtemalStorageState() Environment.MEDIA_MOUNTED手机装有SDCard,并且可以进行读写 获取SDCard的目录:Environment.getExtemalStorageDirectory() //============================================= File saveFile=new File("/sdcard/zhzhg.txt&q

将android项目assets文件夹下的文件复制到SD卡中

<pre name="code" class="html">package com.lapel.activity.html; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import android.content.Context; /** * * 将assets文件夹下的文件复制

android 解决传送中文名文件到模拟器SD卡中

RT,android adb push命令解决中文名文件,把电脑本地的文件导入到Android模拟器AVD的SD卡中 1.通过adb push命令 PS:windows下不稳定,试了下中文名文件能传过去,但文件名为空,linux下可以.若win下该方法不行,参考第二种方法.字幕数字文件名不必说了,肯定没问题. 通过adb push,则可将文件添加到SD卡中.如果想在push的时候修改文件名称的话,只需要修改push的第二个参数改成完整路径(目录+文件名),如E:/videos/welcom.mp

Android -- 写xml到SD卡中

信息类                                                                                          private String body; private String number; private int type; private long id; 四个变量,然后有分别set和get.构造函数分别初始化这四个变量. 生成xml标签函数                                   

android复制数据库到SD卡(网上搜集,未经验证)

android中使用sqlite.复制assets下的数据库到SD卡.支持大于1M的文件 如果使用SD卡,需要在AndroidManifest.xml中设置权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission><uses-permission android:name="android.permission.MO

asserts文件存到外部SD卡里

layout代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_pare

Android数据存储之SD卡

为了更好的存取应用程序的大文件数据,应用程序需要读. 写SD卡上的文件.SD卡大大扩充手机的存储能力. 操作SD首先要加权限: <!--在SDCard中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 往SDCard写入数据权限 --> <uses-permission android:name=&q

Android学习之虚拟SD卡管理

继上一篇SD卡文件读取后,很多朋友表示如何新建并管理虚拟的SD卡呢?下面就让lz带大家了解下SD卡. 其实,要创建SD卡其实还是比较简单的.因为你下载的android的sdk包里面有tools文件夹 .通过它大家就可以创建自己的SD卡了.  具体步骤: 1 打开命令提示符 cmd 2 将根目录转移到你tools文件夹目录下. 3 运行该文件夹下的mksdcard.exe 4 在命令窗口输入 mksdcard 64m D:\avds\.android\avd\sdcard.img (上面的命令创建