使用libwebp和ndk在android 2.x上显示webp图像时发生Outofmemory错误
我使用谷歌开源项目libwebp在安卓1.6--安卓4.0上显示webp图像,并在安卓4.0或更高版本上直接解码webp,我发现在一些安卓手机如appo中,运行libwebp lib时会出现outofmemory错误,给出错误的代码是:使用libwebp和ndk在android 2.x上显示webp图像时发生Outofmemory错误,android,out-of-memory,webp,Android,Out Of Memory,Webp, 我使用谷歌开源项目libwebp在安卓1.6--安卓4.0上显示webp图像,并在安卓4.0或更高版本上直接解码webp,我发现在一些安卓手机如appo中,运行libwebp lib时会出现outofmemory错误,给出错误的代码是:int[]pixels=new int[decoded.length/4] 有人能建议我如何避免这种情况吗?这是我的密码: public static Bitmap getBitmapFromURL(String src) {
int[]pixels=new int[decoded.length/4]代码>
有人能建议我如何避免这种情况吗?这是我的密码:
public static Bitmap getBitmapFromURL(String src) {
HttpURLConnection connection = null;
Bitmap bmp = null;
try {
connection = (HttpURLConnection)
new URL(src).openConnection();
connection.setRequestMethod("GET");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type",
"image/webp");
connection.connect();
//Send request
DataOutputStream wr = new DataOutputStream ( connection.getOutputStream ());
wr.writeBytes ("");
wr.flush ();
wr.close ();
//Get Response
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
while(true) {
String n = rd.readLine();
if(n == null)break;
baos.write(n.getBytes(), 0, n.getByte().length);
baos.write('\n');
}
byte data[] = baos.toByteArray();
// From the lib's exemple
int[] width = new int[] { 0 };
int[] height = new int[] { 0 };
int test = libwebp.WebPGetInfo(data, data.length, width, height);
// test = 0 ! ! !
byte[] decoded = libwebp.WebPDecodeARGB(data, data.length, width, height);
#######################out of memory error is always here
int[] pixels = new int[decoded.length / 4];
#######################
ByteBuffer.wrap(decoded).asIntBuffer().get(pixels);
bmp = Bitmap.createBitmap(pixels, width[0], height[0],Bitmap.Config.ARGB_8888);
} catch (IOException e) {
e.printStackTrace(); }
return bmp;
}
在创建位图之前,请尝试使用System.gc()。这将强制在Android中进行垃圾收集。这可能会释放足够的内存。如果您一直出现内存不足错误,请尝试在代码中查找内存泄漏并修复它
还是不工作?也许可以在C/C++中使用本机代码进行尝试。在这里,您可以高效地管理内存(如果您熟悉C/C++)
试着这样做:
public static ByteArrayOutputStream getBytesFromURL(String src) {
HttpURLConnection connection = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
connection = (HttpURLConnection)
new URL(src).openConnection();
connection.setRequestMethod("GET");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type",
"image/webp");
connection.connect();
//Send request
DataOutputStream wr = new DataOutputStream ( connection.getOutputStream ());
wr.writeBytes ("");
wr.flush ();
wr.close ();
//Get Response
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while(true) {
String n = rd.readLine();
if(n == null)break;
baos.write(n.getBytes(), 0, n.getByte().length);
baos.write('\n');
}
connection.close();
}catch(Exception q){} //Your exception catching here
return baos;
}
public static Bitmap createBitmap(ByteArrayOutputStream baos){
System.gc();
byte data[] = baos.toByteArray();
// From the lib's exemple
int[] width = new int[] { 0 };
int[] height = new int[] { 0 };
int test = libwebp.WebPGetInfo(data, data.length, width, height);
// test = 0 ! ! !
byte[] decoded = libwebp.WebPDecodeARGB(data, data.length, width, height);
int[] pixels = new int[decoded.length / 4];
ByteBuffer.wrap(decoded).asIntBuffer().get(pixels);
bmp = Bitmap.createBitmap(pixels, width[0], height[0],Bitmap.Config.ARGB_8888);
return bmp;
}
在应用程序标记内的manifest.xml文件中添加属性android:largeHeap=“true”。如果在android中使用大量位图,请使用缓存概念。如果不再使用位图,也不要忘记回收位图。基本上System.gc()方法不适用于位图。我尝试调试它,错误总是在这里:int[]像素=新整数[decoded.length/4];而且,使用system.gc()、bitmap.recycle(),所有这些,我已经做过了,在任何应用程序中帮助解决内存异常都不是件难事。您必须记住整个应用程序,因为内存泄漏可能发生在任何地方。还包括诸如byte[]buf=新字节[4096];之类的分配。它从不在任何地方使用,会占用内存。另外,我会将函数分解为它的实际功能。首先与源建立连接并获取所有数据。然后使用另一个函数从该源创建位图,别忘了关闭连接。听起来不错,你能键入一些示例来解释吗?谢谢。谢谢你的建议,但我的项目设置了此属性,它不起作用,你研究过webp库吗,如何通过设置解码webp图像的宽度和高度来减少内存消耗,我发现lib提供了上面添加的方法WebPdecodeGB(byte[]encoded,int length,int[]width,int[]height),最后两个参数的作用是什么:width,height,我认为width和height用于设置解码webp图像的维度,但实际上不是,我如何控制解码的webp图像的尺寸,如果我可以得到一个比初始图像更小的图像,我相信我可以防止这个错误发生,因为更小的位图消耗更少的内存