SOAP - 非常大的XML响应 - OutOfMemoryError

时间:2011-08-03 12:44:09

标签: java android xml web-services soap

首先,此问题类似于 Very large SOAP response - Android- out of memory error 主题。由于我的英语缺点和这个问题的相似性,为了便于理解,一些陈述段落被复制。

我有一个应用程序需要通过SOAP调用将大量数据下载到Web服务。然后将响应发送到显示XML文件的函数。

数据大小超过11MB,每次都有 java.lang.OutOfMemoryError

修改Web服务以提供较少量的数据不是一种选择。

我使用“Http request”来获取数据。我知道:我的请求很好,soapUi和wireshark会回复预期的回复。

但是我的AVD无法通过这一行

HttpResponse httpResponse = httpClient.execute(httpPost);

经过几分钟的工作(在此期间,wireshark恢复了一些预期的查询),这个错误就出现了

 Out of memory on a 16705124-byte allocation.

我尝试将SD卡大小升级到20GB,但仍然是错误。

解析httpResponse可能是下一步,是否可以解析HttpResponse,同时通过exmple将其分成几个部分来接收数据?

你有什么想法吗?

谢谢, Dsandre

3 个答案:

答案 0 :(得分:4)

感谢Graeme,打开连接作为字节流工作。如果它对某人有帮助,这是我的源代码

        //Make a temporary file to save data
        File responseFile = File.createTempFile("SOAP", "xml", context.getFilesDir());      
        int nbCharRead = 0; int i=0; int totalRead = 0;

        //Send query
        OutputStream outputS = url_Connection.getOutputStream();
        Writer w_out = new OutputStreamWriter(outputS);
        w_out.write(webServiceXml);
        w_out.flush();
        w_out.close();


        //Buffers
        BufferedReader bufReader = new BufferedReader(new InputStreamReader(url_Connection.getInputStream()));
        BufferedWriter bufWriter = new BufferedWriter(new FileWriter(responseFile));
        char[] buffer = new char[10000];



        while((nbCharRead = bufReader.read(buffer, 0, 10000)) != -1)
        {
            totalRead += nbCharRead;
            Log.d("Test InputStream", "i: " + i++ +" - " + nbCharRead + " -> " + totalRead);
            bufWriter.write(buffer, 0, nbCharRead );
        }       

        if(bufWriter != null)
        {
            bufWriter.flush();
            bufWriter.close();
        }


        Log.w(MsgLog, "--- Stream Got--- ; Total : " + totalRead);

答案 1 :(得分:3)

您可以将字符串打开连接:

URL url = new URL("www.google.com");
InputStream in = new BufferedInputStream(url.openStream());
byte[] buffer = new byte[1024];
int chunk = 0;
while ((chunk =in.read(buffer ))!=-1)
{
    proccessChunk(chunk);
}
in.close();

从这一点开始,您应该能够对响应进行计量并逐位处理,将每个已处理的块保存为文本文件(或者,如果它是与SQLite的关系数据)。

HTH

答案 2 :(得分:1)

您可能正在将整个响应加载到内存中(可能是一个字符串?)。 Android设备,尤其是在旧硬件和旧版本的操作系统上运行的旧设备,具有有限的vm堆大小。我不记得确切的数字,但快速谷歌表明它低至16mb。

处理Android设备中响应较大的响应的最佳方法是将其作为流读取。我认为最新版本的apache-commons / jakarta httpclient支持流媒体。