0

我正在使用下面的代码从服务器获取 xml 文件,由于 xml 文件又大又重,它崩溃并显示内存不足问题。

 public class Connect {

   static BufferedReader in=null;
   String result=null;
   Context context;
   //Establish connection with web server
      public String HTTPConnect(String uri1,List<NameValuePair> list,Context context)
      {

    this.context=context;
    try {

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(uri1);

        if(list!=null)
        {
        UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list);

        httpPost.setEntity(formEntity);
        }

        HttpResponse httpResponse = httpClient.execute(httpPost);
       in = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
        StringBuffer sb = new StringBuffer("");
        String line = "";
        String NL = System.getProperty("line.separator");

        long heapSize = Runtime.getRuntime().totalMemory();

        if(in!=null)
        {
            while ((line = in.readLine()) != null) {//crasheg here
              sb.append(line + NL);
            }
            in.close();
        }

        result = sb.toString();


}
    catch(UnsupportedEncodingException e)
    {
        String err = (e.getMessage()==null)?"Cant connect to server":e.getMessage();

        ShowDialog();
    }
    catch (MalformedURLException e) {
        String err = (e.getMessage()==null)?"Malformed Exception":e.getMessage();

        ShowDialog();
     } 
     catch(Exception ex)
     {

         String err = (ex.getMessage()==null)?"NetworkConnectionException":ex.getMessage();

         ShowDialog();
     }
    finally {
        if (in != null) {
            try {
                    in.close();
             } catch (Exception ex) {
                 String err = (ex.getMessage()==null)?"Excepion":ex.getMessage();

                 ex.printStackTrace();

            }
        }

     }

    return result;

   }

我知道我正在将整个 XML 复制到 String 中,并且由于文件繁重,它会崩溃。它在小尺寸的 XML 文件中工作正常,但大 xml 文件的替代品是什么。我正在使用 SAX 解析器来解析这个 xml 文件。

[编辑] 下面是 logcat:

 FATAL EXCEPTION: AsyncTask #4
 java.lang.RuntimeException: An error occured while executing doInBackground()
 at android.os.AsyncTask$3.done(AsyncTask.java:200)
 at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
 at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
 at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
 at java.util.concurrent.FutureTask.run(FutureTask.java:137)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
 at java.lang.Thread.run(Thread.java:1096)
 Caused by: java.lang.OutOfMemoryError
 java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:97)
 java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:136)
 java.lang.StringBuilder.append(StringBuilder.java:272)
 java.io.BufferedReader.readLine(BufferedReader.java:452)
 com.kxs.appitize.Connect.HTTPConnect(Connect.java:56)
 com.kxs.appitize.ListRestaurants$Asyn_rest.doInBackground(ListRestaurants.java:168)
 com.kxs.appitize.ListRestaurants$Asyn_rest.doInBackground(ListRestaurants.java:1)
 01-at android.os.AsyncTask$2.call(AsyncTask.java:185)
 at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
  Activity com.kxs.appitize.TabsMainActivity has leaked window    com.android.internal.policy.impl.PhoneWindow$DecorView@44f4fb28 that was originally added here
 android.view.WindowLeaked: Activity com.kxs.appitize.TabsMainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f4fb28 that was originally added here
 at android.view.ViewRoot.<init>(ViewRoot.java:247)
 at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
 at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
 at android.view.Window$LocalWindowManager.addView(Window.java:424)
 at android.app.Dialog.show(Dialog.java:241)
 at com.kxs.appitize.ListRestaurants$Asyn_rest.onPreExecute(ListRestaurants.java:156)
 at android.os.AsyncTask.execute(AsyncTask.java:391)
 at com.kxs.appitize.ListRestaurants.onCreate(ListRestaurants.java:133)
 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
 at android.app.ActivityThread.startActivityNow(ActivityThread.java:2503)
 at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
 at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
at com.kxs.appitize.TabGroupActivity.startChildActivity(TabGroupActivity.java:72)
  at com.kxs.appitize.ListCategories$1.onClick(ListCategories.java:109)
 at android.view.View.performClick(View.java:2408)
 at android.view.View$PerformClick.run(View.java:8816)
 at android.os.Handler.handleCallback(Handler.java:587)
  at android.os.Handler.dispatchMessage(Handler.java:92)
 at android.os.Looper.loop(Looper.java:123)     
 at android.app.ActivityThread.main(ActivityThread.java:4627)
 at java.lang.reflect.Method.invokeNative(Native Method)
 java.lang.reflect.Method.invoke(Method.java:521)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
 at dalvik.system.NativeStart.main(Native Method)
4

2 回答 2

0

尝试使用 inputStream 来解析 XML。inputStrem 不会增加 Android 堆栈大小,并且可以防止大字符串出现 OOM。我对大型 JSON 也有同样的看法,现在,我使用 Jackson 直接从 Stream 解析 JSON。

您可以找到用于解析 XML 的等效库。

于 2013-01-22T11:19:50.787 回答
0

将整个 XML 复制到 String 中并且由于文件繁重

馊主意。首先,您需要将 xml 缓存在一个临时目录中。它永远不应该在 RAM 中。

一旦你这样做了,使用 SAX 来解析文件。在解析过程中,尽量不要将整个结构保留在 RAM 中,而是以一口大小的块进行解析。

于 2013-01-22T11:21:21.517 回答