Android HttpClient内存错误(xml数据)

时间:2011-12-05 23:36:33

标签: android httpclient out-of-memory

我遇到从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

有什么建议吗?

2 个答案:

答案 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 tutorialthis documentation汇总了这个例子。我实际上还没有尝试过,看看它是否有效。