我在将1.8MB图像转换为字节然后加密时面临内存不足异常,最后转换为字符串(日志中打印的长度为1652328)。然后,我将这个字符串附加到某种XML格式上,以便发布真正的问题。在使用StringBuffer
或StringBuilder
或添加到字符串 Out of Memory异常时,会向此pictureString附加一些标记。我该如何解决这个问题?
对于小图片,此问题无法复制。
以下代码将路径path
的图片转换为String
。
fis = new FileInputStream(path);
buffer = new byte[fis.available()];
try {
fis.read(buffer, 0, buffer.length);
String byteString =
com.mobile.android.components.Base64.encodeBytes(buffer);
return byteString;
} catch (IOException ex) {
}
以上byteString
附加到xml帖子,如下所示。
StringBuilder pictureName = new StringBuilder();
pictureName.append(byteString ); //here array out of bound at StringBuilder.extendBuffer
..........
appending continues
已更新
在上面的附加中,编码byteStream
使用密码AES加密,然后附加到StringBuilder
。
答案 0 :(得分:1)
将位图转换为字节数组后立即调用bitmap.recycle();
。这将释放与此位图关联的本机对象,并清除对像素数据的引用。
很明显,从文件流中读取的内存块太大而无法处理。避免一次读取整个文件。一点一点地做。将字符串附加到xml而不使用中间字符串对象。
你可以这样做,以避免在将整个xml文件发送到服务器时加载它。
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Enable POST method
connection.setRequestMethod("POST");
outputStream = new DataOutputStream( connection.getOutputStream() );
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
然后编写边界字符,刷新并关闭流。
答案 1 :(得分:0)
感谢大家的支持。
我最终使用文件操作将代码优化到最大程度。
对于我使用Base64.encodeFileToFile(picturePath, encodedPicturePath);
的编码
我将编码图像保存在文件中。
然后对于加密,我使用了CypherOutPutStream
,其中FileOutputStream在构造函数中传递。所以加密也是使用file完成的。
最后一步是在使用HttpPost时,我曾经将总加密数据发送为StringEntity
,这是OutOfMemeoryException
的最终障碍。我将StringEntity更改为FileEntity
。这减少了堆消耗我的应用程序,从而提高了整体性能和上传容量。
注意: 不要以块的形式加密编码图像,这将改变整体编码数据。它只是一件作品。
失败: 在我使用文件进行编码之前,我将整个图片分块并编码为文件。但是,如果我对编码文件进行解码,则无法获得原始图片。
的问候,沙