最近在写AP要读取大量的图片,这些图片在assets目录下,使用一般的方法经常发生OOM异常。
参考了别人的方法定义Options进行处理。
以下是简单的代码:
String[] images = assets.list(path); //获取图片列表信息
for (String str : images){
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bfOptions.inTempStorage=new byte[32 * 1024];
//AssetFileDescriptor is = assets.openFd(path + java.io.File.separator + str);
//FileInputStream fis = is.createInputStream();
//Bitmap bm = BitmapFactory.decodeFileDescriptor(fis.getFD(), null, bfOptions);
//AssetFileDescriptor is = assets.openFd(path + java.io.File.separator + str);
Bitmap bm = BitmapFactory.decodeStream(assets.open(path + java.io.File.separator + str),
null,
bfOptions);
}
read resource file into temp file to avoid oom problem:
/**
* to avoid OOM crash
* @param context
* @param id
* @return
*/
@SuppressWarnings("finally")
public static Bitmap getBitmapFromId(Context context, int id) {
Bitmap bm = null;
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bfOptions.inTempStorage=mBytes;
FileInputStream fs=null;
File file = new File(context.getFilesDir().getAbsolutePath() + "/" + String.valueOf(id));
//file.deleteOnExit();
try {
if (file.getTotalSpace() > 0)
fs = new FileInputStream(file);
else{
AssetFileDescriptor ad = context.getResources().openRawResourceFd(id);//.openRawResource(id);
FileChannel sourceChannel = new FileInputStream(ad.getFileDescriptor()).getChannel();
copyNIO(sourceChannel, file, ad.getStartOffset(), ad.getLength());
fs = new FileInputStream(file);
}
if(fs!=null)
bm = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
//bm=BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
} finally{
if(fs!=null) {
try {
fs.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return bm;
}
}
private static void copyNIO(FileChannel source, File destination, long startOffset, long length)
throws IOException {
FileChannel destinationChannel = null;
try{
destinationChannel =
new FileOutputStream(destination).getChannel();
source.transferTo(startOffset, length, destinationChannel);
}finally{
}
}
private static byte[] mBytes = new byte[32 * 1024];