I am using the below code to fetch xml file from the server and due to heavy and large xml file, it got crashed and showing Out of memory Issue.
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;
}
I know that that I am copying the whole XML in String and due to heavy file, It gor crashing. It is working fine in small size of XML file, but what are the alternative for large xml file. I am uing SAX parser for parsing this xml file.
[EDIT]
Below is the 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)
Bad idea. First you need to cache the xml in a temporary directory. It should never be in the RAM.
Once you do that use SAX to parse the file. During parsing try not to keep the whole structure in the RAM, instead parse in bite sized chunks.