Android:上传图片数量导致堆大小变大 - 如何解决?

时间:2011-07-09 17:03:00

标签: android

我正在编写应用程序,用户可以在其中拍摄一堆照片(最多20张)并上传到服务器。图像需要一起上传。

这是我的逻辑:

  1. 拍摄每张照片,在屏幕上显示拇指并将SD上的照片调整为800x600(质量为90)
  2. 创建对象,将属性(图像)填充为Base64字符串
  3. 使用GSON序列化对象
  4. 上传字符串
  5. 在测试时,我在处理图像时遇到了“Out of Memory”错误。我想,这就是所有StackOverflow抱怨的地方 - 这是BitmapFactory的一些错误。是的,在调整图像大小时,错误主要显示,但与此操作无关。

    当我拍照并处理它们(调整大小等)时 - 堆大小保持在7-8mb以下。它比我常用的应用程序状态仅多2-3Mb。

    当我将这些图像提交给服务器并且GSON + Base64编码器发挥作用 - 而不是“爆炸”时我得到了这个:

    enter image description here

    嗯 - 正如您所见 - 在进程完成后分配的内存按预期降低但堆大小保持不变。现在,当我拍摄更多照片或使用应用程序执行某些操作时 - 我开始出现内存错误。

    这是我上传JSON的代码。有关改进或处理类似问题的任何建议吗?也许我可以将JSON流式传输到文件中并从文件或其他内容中执行http?

    while (!c.isAfterLast())
            {
                String data = c.getString(colObjectData);
                TrailerInspection trailerInspection = MyGsonWrapper.getMyGson().fromJson(data, TrailerInspection.class);
    
                //Load image data
                for (TrailerUnitInspection trailerUnitInspection : trailerInspection.UnitInspections)
                {
                    for (FileContainer fileContainer : trailerUnitInspection.Images)
                    {
                        fileContainer.dataFromFile(mContext);
                    }
                }
    
                data = MyGsonWrapper.getMyGson().toJson(trailerInspection);
    
                MyHttpResponse response = processPOST("/trips/" + c.getString(colTripId) + "/trailerinspection", data);
    
                if (response.Code ==  HttpURLConnection.HTTP_OK)
                {
                    processed.add(c.getString(colGId));
                }
    
                c.moveToNext();
            }
            c.close();
    

1 个答案:

答案 0 :(得分:3)

问题是你正在内部存储器中创建并保留准备发送的整个字符串。

String data = MyGsonWrapper.getMyGson().toJson(trailerInspection);

此字符串可能非常大。您应该将数据以块的形式流式传输到服务器 我还没有使用过gson,但在文档中我发现了JsonWriter之类的东西。看看这堂课。

更新:

ContentProducer cp = new ContentProducer() {
    public void writeTo(OutputStream outstream) throws IOException {
        JsonWriter writer = new JsonWriter(new OutputStreamWriter(outstream, "UTF-8"));
        // write code here
        writer.flush();
    }
};
HttpEntity entity = new EntityTemplate(cp);
HttpPost httppost = new HttpPost("http://server.address");
httppost.setEntity(entity);