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

Android 安卓:上传大量图片导致堆变大-如何解决?,android,Android,我正在编写一个应用程序,用户可以拍摄大量照片(最多20张)并上传到服务器。图片需要一起上传 我的逻辑是: 拍摄每张照片,在屏幕上显示拇指,并将SD上的照片大小调整为800x600,质量为90 创建对象,将属性(图像)填充为Base64字符串 使用GSON序列化对象 上传字符串 在测试过程中,当我处理图像时,我得到了“内存不足”的错误。我想这就是StackOverflow抱怨的地方——这是BitmapFactory的一些bug。是的,错误主要在调整图像大小时出现,但与此操作无关 当我拍照并处理它们

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

我的逻辑是:

  • 拍摄每张照片,在屏幕上显示拇指,并将SD上的照片大小调整为800x600,质量为90
  • 创建对象,将属性(图像)填充为Base64字符串
  • 使用GSON序列化对象
  • 上传字符串
  • 在测试过程中,当我处理图像时,我得到了“内存不足”的错误。我想这就是StackOverflow抱怨的地方——这是BitmapFactory的一些bug。是的,错误主要在调整图像大小时出现,但与此操作无关

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

    当我将这些图像提交到服务器,GSON+Base64编码器开始工作时,它会“爆炸”,我得到以下结果:

    正如您所看到的,在进程完成后,分配的内存按预期减少,但堆大小保持不变。现在,当我拍摄更多照片或使用应用程序做一些事情时,我开始将这些错误从内存中清除

    这是我上传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();
    

    问题是您正在创建整个字符串并将其保存在内存中,准备发送

    String data = MyGsonWrapper.getMyGson().toJson(trailerInspection);
    
    这根绳子可能很大。您应该将数据分块传输到服务器。
    我还没有用过gson,但在文档中我发现了类似的东西。看看这门课

    更新:

    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);
    

    我来看看JsonWriter。但是如何将该流传递到HttpClient?这需要StringEntity.。有一个例子:这个例子中使用的PostMethod似乎已经从Android中删除了。我是否正确理解我的目标是将对象流式传输到文件(内部或SD),而不是直接从SD进行http post流式传输?如果我从GSON内存创建内存中的流,还需要纳税吗?再次感谢。我花了一段时间来理解“//在这里编写代码”:)因为我的对象非常复杂,我必须使用JsonWriter手动逐个属性地完成它。但现在一切都好了。在最坏的情况下,堆大小会增加3-4mb。呸。。