java.lang.OutOfMemoryError

异常信息:

java.lang.OutOfMemoryError ..

BitmapFactory.nativeDecodeStream(Native Method).....


需要做个东东里面的一小个功能是,将“图库”中的图片动态地添加到GridView中,但是当我添加到一定数量(比如5 张或者6张的时候),系统就卡死报异常说内存空间不足了


用来用来加载图片的方式为  picBitmap = BitmapFactory.decodeFile(picPath); (这种方法把图片都加载到内存中了)


所以去百度了一下,下面贴一串比较好的代码


//第一种方法: 添加图片比较大的差不多可以弄到20张,不过还是卡!

private Bitmap getBitmap(String path)   {

		Bitmap bm = null;
		
		BitmapFactory.Options bfOptions=new BitmapFactory.Options();
	    bfOptions.inDither=false;                     
	    bfOptions.inPurgeable=true;                 
	    bfOptions.inInputShareable=true;             
	    bfOptions.inTempStorage=new byte[32 * 1024]; 
	    

	    File file=new File(path);
	    FileInputStream fs=null;
	    try {
	        fs = new FileInputStream(file);
	    } catch (FileNotFoundException e) {
	        e.printStackTrace();
	    }

	    try {
	        if(fs!=null) 
	        	bm = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
	    } catch (IOException e) {
	        e.printStackTrace();
	    } finally{ 
	        if(fs!=null) {
	            try {
	                fs.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	    return bm;
	}

我想这可能是decodeStream/decodeFile中本地函数的问题。我很确定当使用decodeFileDescriptor时一个不同的本地方法被调用。我读到的也是“图片(Bitmaps)并不是指派给一个标准的java路径,但是是通过本地调用的;这个分配是在虚拟的堆外完成的,但是是被认为针对它的!



//第二种方法:这种方法的话更好,推荐

private Bitmap getBitpMap(Uri uri) {
		ParcelFileDescriptor pfd;
		try {
			pfd = getApplicationContext().getContentResolver().openFileDescriptor(uri, "r");
		} catch (IOException ex) {
			return null;
		}
		java.io.FileDescriptor fd = pfd.getFileDescriptor();
		BitmapFactory.Options options = new BitmapFactory.Options();
		// 先指定原始大小
		options.inSampleSize = 1;
		// 只进行大小判断
		options.inJustDecodeBounds = true;
		// 调用此方法得到options得到图片的大小
		BitmapFactory.decodeFileDescriptor(fd, null, options);
		// 我们的目标是在800pixel的画面上显示。
		// 所以需要调用computeSampleSize得到图片缩放的比例
		options.inSampleSize = computeSampleSize(options, 800);
		// OK,我们得到了缩放的比例,现在开始正式读入BitMap数据
		options.inJustDecodeBounds = false;
		options.inDither = false;
		options.inPreferredConfig = Bitmap.Config.ARGB_8888;
		// 根据options参数,减少所需要的内存
		Bitmap sourceBitmap = BitmapFactory.decodeFileDescriptor(fd, null,
				options);
		return sourceBitmap;
	}

	// 这个函数会对图片的大小进行判断,并得到合适的缩放比例,比如2即1/2,3即1/3
	static int computeSampleSize(BitmapFactory.Options options, int target) {
		int w = options.outWidth;
		int h = options.outHeight;
		int candidateW = w / target;
		int candidateH = h / target;
		int candidate = Math.max(candidateW, candidateH);
		if (candidate == 0)
			return 1;
		if (candidate > 1) {
			if ((w > target) && (w / candidate) < target)
				candidate -= 1;
		}
		if (candidate > 1) {
			if ((h > target) && (h / candidate) < target)
				candidate -= 1;
		}

		return candidate;
	}



你可能感兴趣的:(java.lang.OutOfMemoryError)