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全体を文字列にコピーしていて、ファイルが重いためにクラッシュしていることを知っています。小さいサイズの XML ファイルでは問題なく動作しますが、大きい xml ファイルの代わりになるものは何ですか。このxmlファイルを解析するためにSAXパーサーを使用しています。

[編集] 以下は 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全体を文字列でコピーし、ファイルが重いため

悪いアイデア。まず、一時ディレクトリにxmlをキャッシュする必要があります。RAMには絶対に入れないでください。

これを行ったら、SAXを使用してファイルを解析します。解析中は、構造全体をRAMに保持しないようにしてください。代わりに、一口サイズのチャンクで解析してください。

于 2013-01-22T11:21:21.517 に答える