我有一个Android应用程序可以用来存储所有葡萄酒的有用信息(名称,年份,价格,有多好......)。为了允许用户在彼此之间交换信息或者在不同的设备上交换信息,我有一个序列化机制,允许用户:
这很好用。
但是,前段时间,我收到了一个请求,也可以导出可添加到Wine描述中的图片。所以我修改了我的Wine类(实现Serializable)来添加byte []属性。
这就是麻烦开始的地方:用图片导出我的葡萄酒时,我得到 StreamCorruptedException 。
java.io.StreamCorruptedException
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1528)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at [...].WineVectorSerializer$2.run(WineVectorSerializer.java:84)
我玩弄了一下我从Bitmap创建字节数组的方式并保持缩小尺寸,直到它最终起作用。我不知道为什么,但是当我的.ser文件达到~1.3Mo时会触发异常。
因此,如果我以蹩脚的质量导出所有图片,一切正常。如果我稍微增加它,那么当导出文件变得“太大”时我会得到异常。 (不到2 Mo就是那么多 - 我的SD卡上有足够的可用空间。)
我试图在每次调用writeObject之间添加一个Thread.sleep(1000),但它没有帮助。
FileOutputStream fos = new FileOutputStream(filename);
final ObjectOutputStream out = new ObjectOutputStream(fos);
for (Wine aWine: data) {
try {
aWine.loadImage();
out.writeObject(aWine);
out.flush();
}
catch (IOException e) {
Log.e("Serialize", "Error during export");
exportError = true;
handle.sendMessage(handle.obtainMessage());
break;
}
finally {
aWine.freeImage();
}
handle.sendMessage(handle.obtainMessage());
}
out.close();
在上面的代码段中,您可以看到我调用 loadImage() [请参阅下一个代码段]和 freeImage()。第一个:
在Wine序列化之后,对 freeImage()的调用将此byte []设置为null,以允许垃圾收集器释放一些内存并避免内存不足异常 - 这会出口300多张带图片的葡萄酒时必然会发生。
public void loadImage() {
set_imageBytes(null);
if (_imagePath != null && _imagePath.length() > 0) {
File aImageFile = new File(_imagePath);
// Just to get the image size
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(aImageFile.getAbsolutePath(), options);
// No more than 500px
int largestEdge = Math.max(options.outHeight, options.outWidth);
int ratio = largestEdge/500;
options.inJustDecodeBounds = false;
options.inSampleSize = ratio;
Bitmap aBitmap = BitmapFactory.decodeFile(aImageFile.getAbsolutePath(), options);
if (aBitmap != null) {
Log.i("Serialize", "There is an image to serialize");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
aBitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream);
set_imageBytes(stream.toByteArray());
}
}
}
在上面的代码中,我设法通过在aBitmap.compress中将max width设置为200px并将质量设置为5%来避免异常。
如果有人能解释为什么这个异常发生在1.3 Mo屏障周围,那就太棒了。 在此先感谢:)
答案 0 :(得分:0)
让它发挥作用。我只是愚蠢地误读了SD卡上的可用空间,当没有空间可以写入时抛出异常。