title: XMLPullParser Out of Memory (Android)
body: <p>I'm stuck in trying to handle an out of memory error in Android while trying to parse a response from a HTTPTransfer using SOAP. Overall the transport is fine until I ask for a large image. The image is about 901KB is size, but for some reason it causes Android to run out of memory while parsing it. Here is the code:</p>
  
  <pre><code>public void parseWithPullParser(InputStream is) {
      try {
  
          XmlPullParser parser = GenericHandler.createParser(this.parserTypeName); // new
          // org.xmlpull.mxp1.MXParser();
  
          parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
          parser.setInput(is, null);
          Log.d(TAG, "Name of class being parsed: " + resultClassName);
          for (int eventType = parser.getEventType(); eventType != XmlPullParser.END_DOCUMENT; eventType = parser
                  .next()) {
              switch (eventType) {
              case XmlPullParser.START_DOCUMENT: {
                  break;
              }
              case XmlPullParser.START_TAG: {
                  String name = parser.getName();
                  String prefix = null;
                  if ("Envelope".equals(name) || "Header".equals(name) || "Body".equals(name)
                          || "return".equals(name)) {
                      prefix = "env:"; // TODO: Hack-Hack-Hack... :)
                  }
                  name = prefix == null ? name : prefix + ":" + name;
                  this.startElement(name);
                  break;
              }
              case XmlPullParser.TEXT: {
                  String text = parser.getText();
                  if (text != null) {
                      if (resultClassName.contains("ImageSingle")) {
                          Log.d(TAG, "Text passage: " + text);
                      }
                      if (content == null) {
                          content = new String();
                      }
                      content = text; // Original system used a string builder
                      // but only for a single section, for
                      // large images this was a problem, but
                      // a single string object appears to
                      // have the same affect
                      // char[] ch = text.toCharArray(); //original
                      // this.characters(ch, 0, ch.length); //original
                  }
                  break;
              }
  
              case XmlPullParser.END_TAG: {
                  String name = parser.getName();
                  String prefix = null;
                  if ("Envelope".equals(name) || "Header".equals(name) || "Body".equals(name)
                          || "return".equals(name)) {
                      prefix = "env:"; // TODO: Hack-Hack-Hack... :)
                  }
                  name = prefix == null ? name : prefix + ":" + name;
                  this.endElement(name);
                  break;
              }
              default: {
                  break;
              }
              }
  
          }
      } catch (Exception except) {
          Log.e(this.getClass().getSimpleName(), except.toString(), except);
      }
  }
  </code></pre>
  
  <p>I found the library <a href="http://wiki.javaforum.hu/display/ANDROIDSOAP/Home" rel="nofollow">here</a>. The issue (I believe) is when it does parser.next() because it reads in the image data (which is sent to me in a Base64 encoded string) and then tries to do parser.getText(). If I am understanding everything properly the way it outputs the string is by repetitive calls to the internal stringbuilder that will keep repeating .toString() to itself until it generates the parsed string. The image in question is about 1.2 million characters and as each character is 2 bytes, that implies 2.4 MB (the image though is 901 KB originally..but I guess there's extra data that gets parsed?) if I understand this correctly. But the heap expands to over 16 MB which causes the app to crash on stock VM settings when this method is called. </p>
  
  <p>I doubt this is a unique situation and as such would love to hear how others have handled this problem. I've thought about maybe just throwing the string to a file on the SD card to keep it out of memory but it seems that for me to get the string I need parser.getText...which therein lies the problem.</p>