java - 内存不足错误 : When receiving XML response of 2. 3 MB

标签 java android response out-of-memory

以下是连接到 Web 服务并从服务器接收大约 2.3MB 的 XML 响应的简单方法,我得到了 OutOfMemoryError ( I've referred this ) 但是找不到路,卡得很厉害

public synchronized String getUpdates(boolean news) throws Exception {
        String response = null; 
        HttpPost httppost;
        DefaultHttpClient httpclient;
        ResponseHandler <String> res=new BasicResponseHandler();  
        List<NameValuePair> nameValuePairs;
        httppost = new HttpPost(context.getString(R.string.SYNCURL));  
        HttpParams params = new BasicHttpParams();  
        HttpProtocolParams.setContentCharset(params, "UTF-8");

        String lastupdate = null;
        SharedPreferences preferences = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
        lastupdate = preferences.getString(LAST_UPDATE, DatabaseHelper.updateDate);
        if(news) lastupdate = preferences.getString(LAST_UPDATE_NEWS, lastupdate);

        httpclient = new DefaultHttpClient(params);
        nameValuePairs = new ArrayList<NameValuePair>(2);  
        nameValuePairs.add(new BasicNameValuePair("reqDTTM", lastupdate));
        if(news)nameValuePairs.add(new BasicNameValuePair("doAction", "news"));
        if(!preferences.getString(LAST_UPDATE, "").equalsIgnoreCase(DatabaseHelper.updateDate)) {
            String timezon = UDFHelper.getTimeZon(context);
            nameValuePairs.add(new BasicNameValuePair("tz", timezon));
        }
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));  
        response = httpclient.execute(httppost, res);
        return response;
}

这会导致在 String response 中尝试检索大文本时出现问题:

response = httpclient.execute(httppost, res);

我将响应存储在字符串中。那是问题吗?什么是替代解决方案?

这是 LogCat

09-23 10:07:31.654: INFO/ActivityManager(59): Displayed activity uk.co.dodec.rcgpapp/.SplashScreen: 1267 ms (total 1267 ms)
09-23 10:07:35.854: INFO/dalvikvm-heap(334): Grow heap (frag case) to 3.213MB for 262160-byte allocation
09-23 10:07:38.203: INFO/dalvikvm-heap(334): Grow heap (frag case) to 3.586MB for 524304-byte allocation
09-23 10:07:42.753: INFO/dalvikvm-heap(334): Grow heap (frag case) to 4.336MB for 1048592-byte allocation
09-23 10:07:52.024: INFO/dalvikvm-heap(334): Grow heap (frag case) to 5.836MB for 2097168-byte allocation
09-23 10:08:09.844: INFO/dalvikvm-heap(334): Grow heap (frag case) to 8.836MB for 4194320-byte allocation
09-23 10:08:09.864: INFO/ActivityManager(59): Process com.android.mms (pid 227) has died.
09-23 10:08:45.984: INFO/dalvikvm-heap(334): Forcing collection of SoftReferences for 8388624-byte allocation
09-23 10:08:46.033: ERROR/dalvikvm-heap(334): Out of memory on a 8388624-byte allocation.
09-23 10:08:46.033: INFO/dalvikvm(334): "AsyncTask #1" prio=5 tid=7 RUNNABLE
09-23 10:08:46.033: INFO/dalvikvm(334):   | group="main" sCount=0 dsCount=0 s=N obj=0x43e54fd8 self=0x224d58
09-23 10:08:46.033: INFO/dalvikvm(334):   | sysTid=340 nice=10 sched=0/0 cgrp=bg_non_interactive handle=2248344
09-23 10:08:46.033: INFO/dalvikvm(334):   | schedstat=( 1248172861 2043417240 1093 )
09-23 10:08:46.033: INFO/dalvikvm(334):   at org.apache.http.util.CharArrayBuffer.expand(CharArrayBuffer.java:~59)
09-23 10:08:46.033: INFO/dalvikvm(334):   at org.apache.http.util.CharArrayBuffer.append(CharArrayBuffer.java:77)
09-23 10:08:46.033: INFO/dalvikvm(334):   at org.apache.http.util.EntityUtils.toString(EntityUtils.java:136)
09-23 10:08:46.033: INFO/dalvikvm(334):   at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
09-23 10:08:46.033: INFO/dalvikvm(334):   at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:76)
09-23 10:08:46.033: INFO/dalvikvm(334):   at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:59)
09-23 10:08:46.033: INFO/dalvikvm(334):   at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:657)
09-23 10:08:46.033: INFO/dalvikvm(334):   at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627)
09-23 10:08:46.033: INFO/dalvikvm(334):   at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616)
09-23 10:08:46.033: INFO/dalvikvm(334):   at uk.co.dodec.rcgpapp.helper.HttpHelper.getUpdates(HttpHelper.java:172)
09-23 10:08:46.033: INFO/dalvikvm(334):   at uk.co.dodec.rcgpapp.SplashScreen.getUpdate(SplashScreen.java:155)
09-23 10:08:46.033: INFO/dalvikvm(334):   at uk.co.dodec.rcgpapp.SplashScreen$getUpdates.doInBackground(SplashScreen.java:126)
09-23 10:08:46.033: INFO/dalvikvm(334):   at uk.co.dodec.rcgpapp.SplashScreen$getUpdates.doInBackground(SplashScreen.java:1)
09-23 10:08:46.043: INFO/dalvikvm(334):   at android.os.AsyncTask$2.call(AsyncTask.java:185)
09-23 10:08:46.043: INFO/dalvikvm(334):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
09-23 10:08:46.043: INFO/dalvikvm(334):   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
09-23 10:08:46.043: INFO/dalvikvm(334):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
09-23 10:08:46.043: INFO/dalvikvm(334):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
09-23 10:08:46.043: INFO/dalvikvm(334):   at java.lang.Thread.run(Thread.java:1096)
09-23 10:10:37.353: WARN/dalvikvm(334): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
09-23 10:10:37.375: ERROR/AndroidRuntime(334): FATAL EXCEPTION: AsyncTask #1
09-23 10:10:37.375: ERROR/AndroidRuntime(334): java.lang.RuntimeException: An error occured while executing doInBackground()
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at java.lang.Thread.run(Thread.java:1096)
09-23 10:10:37.375: ERROR/AndroidRuntime(334): Caused by: java.lang.OutOfMemoryError
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at org.apache.http.util.CharArrayBuffer.expand(CharArrayBuffer.java:59)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at org.apache.http.util.CharArrayBuffer.append(CharArrayBuffer.java:77)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:136)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:76)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:59)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:657)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at uk.co.dodec.rcgpapp.helper.HttpHelper.getUpdates(HttpHelper.java:172)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at uk.co.dodec.rcgpapp.SplashScreen.getUpdate(SplashScreen.java:155)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at uk.co.dodec.rcgpapp.SplashScreen$getUpdates.doInBackground(SplashScreen.java:126)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at uk.co.dodec.rcgpapp.SplashScreen$getUpdates.doInBackground(SplashScreen.java:1)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
09-23 10:10:37.375: ERROR/AndroidRuntime(334):     ... 4 more
09-23 10:10:37.393: WARN/ActivityManager(59):   Force finishing activity uk.co.dodec.rcgpapp/.SplashScreen

我试过以下没用

HttpResponse r = httpclient.execute(httppost);

HttpEntity entity = r.getEntity();

InputStream in = new ByteArrayInputStream(EntityUtils.toByteArray(entity));

File fl = new File(Environment.getDataDirectory().toString() + "/data/" + context.getPackageName() + "/" + FOLDER_NAME);
if(!fl.exists()) fl.mkdir();

String PATH = Environment.getDataDirectory().toString() + "/data/" + context.getPackageName() + "/" + FOLDER_NAME + "/" + "update.xml";
FileOutputStream f = new FileOutputStream(PATH);

byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
    f.write(buffer, 0, len1);
}
f.close();

最佳答案

这确实是个问题:不要那样做。您应该将响应写入文件或解析流,但绝对不要尝试生成 2.3 MB 的字符串。编写一个返回 HttpEntity 的响应处理程序在响应后面,然后使用 getContent 获取 InputStream方法,然后将其保存到文件中,然后处理该文件。

关于java - 内存不足错误 : When receiving XML response of 2. 3 MB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7524403/

相关文章:

java - 带有 Spring Security 的 AspectJ

java - 使用 next() 时扫描仪中出现 NoSuchElementException

java - 如何在 Scala 中制作功能齐全的不可变类?

Android:以编程方式添加的 TableLayout 中的 View 未显示

android - 向 Toast 显示查询

Java 应用程序未在 Eclipse Galileo 中运行

java - 在构建 iPhone/Android 应用程序方面需要帮助

java - 如何使用servlet在浏览器中编写pdf文件?

javascript - 尝试与服务 worker 一起显示离线页面,但即使在离线状态下,我的请求也会收到 200 响应

javascript - 爪子:将响应字段复制到环境中