Java SOAP-非常大的XML响应-OutOfMemoryError

Java SOAP-非常大的XML响应-OutOfMemoryError,java,android,xml,web-services,soap,Java,Android,Xml,Web Services,Soap,首先,这个问题看起来像一个主题。由于我英语的弱点和这个问题的相似性,为了便于理解,一些语句段被抄袭了 我有一个应用程序,需要通过对Web服务的SOAP调用下载大量数据。然后将响应发送到显示XML文件的函数 数据的大小超过11MB,我每次都有一个java.lang.OutOfMemoryError 修改Web服务以提供较少的数据量不是一个选项 我使用“Http请求”获取数据。我知道:我的请求很好,soapUi和wireshark会返回预期的响应 但是我的AVD不能通过这条线 HttpRespons

首先,这个问题看起来像一个主题。由于我英语的弱点和这个问题的相似性,为了便于理解,一些语句段被抄袭了

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

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

修改Web服务以提供较少的数据量不是一个选项

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

但是我的AVD不能通过这条线

HttpResponse-HttpResponse=httpClient.execute(httpPost)

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

 Out of memory on a 16705124-byte allocation.
我尝试将SD卡大小升级到20GB,但仍然出错

解析httpResponse可能是下一步,是否可以在httpResponse接收数据时通过Example将其分割成几个部分来解析它

你有什么想法吗

谢谢,
Dsandre

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


在android设备中处理如此大响应的最佳方法是将其作为流读取。我认为最新版本的apache commons/jakarta httpclient支持流式传输。

您可以以字节流的形式打开连接:

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

感谢格雷姆,以字节流的形式打开连接是可行的。如果它能对某人有所帮助,这是我的源代码

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

你链接到一个有答案的问题。我建议你试试。没错,这就是我问这个问题的原因,因为我提出的解决方案与我的案例不兼容。我试着这么做,谢谢你的第二个选择:。但是由于HttpResponse失败,我无法创建用于流的HttpEntity。您可以尝试使用executeMethod而不是execute。请参阅:execute()方法的问题是,如果跟踪HttpClient.execute,则它已经开始读取和处理响应,因此可能会导致分配错误。但是我不确定,请尝试executeMethod,看看您是否能够通过executeMethod并继续阅读响应流。谢谢。找不到executeMethod,httpClient类型为“DefaultHttpClient”。我选择它是因为org.apach.http.client.HttpClient是一个接口,我不知道如何实现我自己的HttpClient类您的解决方案工作,我使用
InputStream
获取数据。非常感谢。但现在出现了一个最新的问题:我不能获得超过28847个字节,为什么?我尝试了许多选项(有/没有超时,…)。流存储在缓冲区(
byte[104876]
like)上,缓冲区写在临时文件上。你能告诉我什么是webServiceXml吗?我如何替换这行代码androidHttpTransport.call(SOAP\u ACTION\u async,信封);以使其正常工作。因为我在调用Web服务时在这一行上遇到错误。任何帮助都将非常有用。也参考了其他链接,但没有合适的代码可用。