XMLPullParser Out of Memory (Android) - PullRequest
       12

XMLPullParser Out of Memory (Android)

1 голос
/ 13 марта 2011

Я застрял в попытке обработать ошибку нехватки памяти в Android при попытке проанализировать ответ от HTTPTransfer с использованием SOAP. В целом транспорт в порядке, пока я не попросил большое изображение. Размер изображения составляет около 901 КБ, но по какой-то причине в Android происходит нехватка памяти при его анализе. Вот код:

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);
    }
}

Я нашел библиотеку здесь . Проблема (я полагаю) в том, что он выполняет parser.next (), потому что он считывает данные изображения (которые отправляются мне в кодированной строке Base64), а затем пытается выполнить parser.getText (). Если я все правильно понимаю, то, как она выводит строку, - это повторяющиеся вызовы внутреннего строителя строк, который будет повторять .toString () сам по себе, пока не сгенерирует проанализированную строку. Размер рассматриваемого изображения составляет около 1,2 миллиона символов, а размер каждого символа составляет 2 байта, что означает 2,4 МБ (хотя изначально изображение составляет 901 КБ, но я полагаю, что анализируются дополнительные данные?), Если я правильно понимаю. Но объем кучи увеличивается до более чем 16 МБ, что вызывает сбой приложения на стандартных настройках виртуальной машины при вызове этого метода.

Я сомневаюсь, что это уникальная ситуация, и поэтому хотелось бы услышать, как другие справились с этой проблемой. Я подумал, может быть, просто выбросить строку в файл на SD-карте, чтобы сохранить ее в памяти, но мне кажется, что для получения строки мне нужен parser.getText ... в этом и заключается проблема.

1 Ответ

0 голосов
/ 21 февраля 2014

В соответствии с комментарием Стефана Бранчика, мой комментарий извлечен и помечен как ответ на мой вопрос.

Для всех, кто сталкивался с этим, я, в конце концов, использовал парсер саксофона, у меня появилась идея здесь: helloandroid.com / tutorials / newsdroid-rss-reader

...