我遇到从xml web服务读取大数据的问题,xml文件大约是5.5Mb,代码崩溃并引发内存不足错误
这是我的功能
private static HttpResponse executePostHttpRequest(String baseUrl,
String names[],
String values[]) throws ClientProtocolException,
IOException {
final HttpClient client = newHttpClientInstance();
HttpPost request = new HttpPost(baseUrl);
boolean haveData = (names != null) && (values != null);
// if we have data, form it into request
if (haveData) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(values.length);
for (int i = 0; i < values.length; i++) {
nameValuePairs.add(new BasicNameValuePair(names[i], values[i]));
}
try {
request.setEntity(new UrlEncodedFormEntity(nameValuePairs, "utf-8"));
} catch (UnsupportedEncodingException e) {
request.setEntity(new UrlEncodedFormEntity(nameValuePairs));
}
}
request.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// return response created by executing this request
return client.execute(request);
}
和 这是我的笨蛋
12-05 23:30:31.813: I/dalvikvm-heap(443): Forcing collection of SoftReferences for 4842758-byte allocation
12-05 23:30:31.964: D/dalvikvm(443): GC freed 0 objects / 0 bytes in 143ms
12-05 23:30:31.964: E/dalvikvm-heap(443): Out of memory on a 4842758-byte allocation.
12-05 23:30:31.964: I/dalvikvm(443): "pool-1-thread-3" prio=5 tid=35 RUNNABLE
12-05 23:30:31.977: I/dalvikvm(443): | group="main" sCount=0 dsCount=0 s=N obj=0x44f92608 self=0x3d92a0
12-05 23:30:31.977: I/dalvikvm(443): | sysTid=460 nice=0 sched=0/0 cgrp=default handle=3901200
12-05 23:30:31.984: I/dalvikvm(443): at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:~97)
12-05 23:30:31.984: I/dalvikvm(443): at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:155)
12-05 23:30:31.984: I/dalvikvm(443): at java.lang.StringBuilder.append(StringBuilder.java:216)
12-05 23:30:31.984: I/dalvikvm(443): at com.XXXXXXXXX.api.HttpUtils.convertStreamToString(HttpUtils.java:308)
12-05 23:30:31.993: I/dalvikvm(443): at com.XXXXXXXXX.api.HttpUtils.responseToString(HttpUtils.java:331)
12-05 23:30:31.993: I/dalvikvm(443): at com.XXXXXXXXX.api.HttpUtils.executeRequest(HttpUtils.java:208)
12-05 23:30:31.993: I/dalvikvm(443): at com.XXXXXXXXX.api.HttpUtils.access$0(HttpUtils.java:188)
12-05 23:30:31.993: I/dalvikvm(443): at com.XXXXXXXXX.api.HttpUtils$3.run(HttpUtils.java:171)
12-05 23:30:31.993: I/dalvikvm(443): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
12-05 23:30:31.993: I/dalvikvm(443): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
12-05 23:30:31.993: I/dalvikvm(443): at java.lang.Thread.run(Thread.java:1096)
12-05 23:30:33.024: D/HttpUtils(443): Throwable: java.lang.OutOfMemoryError
12-05 23:30:35.383: D/HttpUtils(443): Throwable: java.lang.OutOfMemoryError
有什么建议吗?
答案 0 :(得分:2)
压缩xml,文本压缩得很好,我有一个类似的问题(JSON而不是XML),它不仅解决了我的内存问题,它还使应用程序的速度提高了一百万倍。
在我的特定情况下,JSON字符串从5 Mb变为200kb。
朝这个方向看:Gzip in Android
答案 1 :(得分:0)
尝试直接读取实际输入流。这将允许您使用XMLPullParser,这意味着您在解析它时不必将整个XML文件保留在内存中。拉解析通过在获得元素时解析元素并依赖状态(如SAX解析器)来跟踪您的位置。这是一个需要的概念,可以让您将xml文件视为XML标记流。
你想做的事情如下:
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = factory.newPullParser();
parser.setInput(new InputStreamReader(in));
XmlUtils.beginDocument(parser,"results");
int eventType = parser.getEventType();
do{
XmlUtils.nextElement(parser);
parser.next();
eventType = parser.getEventType();
if(eventType == XmlPullParser.TEXT){
Log.d("test",parser.getText());
}
//...Handle other types of events...
} while (eventType != XmlPullParser.END_DOCUMENT) ;
}
finally {
urlConnection.disconnect();
}
我从this tutorial和this documentation汇总了这个例子。我实际上还没有尝试过,看看它是否有效。