Должен ли я использовать что-то другое, чем getResource (). GetStringArray (), чтобы заполнить большой массив? - PullRequest
5 голосов
/ 19 августа 2010

Следуя примеру Android для заполнения ListView , я запрашиваю массив из моего strings.xml , используя Activity.getResource (). GetStringArray () :

String [] mDefinitions = getResources().getStringArray(R.array.definition_array);

Документация по этому методу довольно ясна, и я не ожидал, что с ним возникнут какие-либо проблемы:

Возвращает массив строк, связанный с определенным идентификатором ресурса.

Этот подход сработал, как и ожидалось, для небольших наборов данных. Однако, когда я заполнил strings.xml полным набором данных (около 2000 записей), я обнаружил, что приложение упало при попытке загрузить ресурс. Я заметил эту ошибку в журнале консоли:

Переполнение ReferenceTable (max = 512)

Играя с количеством элементов в моем массиве строк Я подтвердил, что ошибка воспроизводима, когда количество элементов превышает ~ 700 записей.

Погуглив проблему, обнаружилось несколько примеров других разработчиков , имеющих такую ​​же проблему , но я не могу найти ничего в документации Android, чтобы объяснить это.

Кто-то столкнулся с проблемой создания проблемы для проблемы на странице кода Google Android, но ни она, ни любая из постов, с которыми я столкнулся, не получили удовлетворительного ответа.

Я неправильно подхожу к проблеме? Должен ли я сам заполнять данные (загружать файл и анализировать JSON или аналогичный) и полностью избежать этой проблемы? Такое ощущение, что я что-то упускаю здесь очевидное.

Ответы [ 2 ]

7 голосов
/ 26 августа 2010

Мне нужно иметь возможность анализировать большие XML-файлы для моего конкретного приложения (у меня уже были данные, закодированные таким образом, и я хотел сохранить их целостность).

Итак, моей первой попыткой было использование getStringArray , которая страдает от проблемы, описанной в вопросе:

String [] mDefinitions = getResources().getStringArray(R.array.definition_array);

Моя вторая попытка страдает от того же ограничения, которое я включил в getStringArray . Как только я попытался обработать больший XML-файл (> 500 КБ), у меня произошел сбой DalvikVM на getXml :

 XmlResourceParser parser = getResources().getXml(R.xml.index);

 try {
     int eventType = parser.getEventType();

     while (eventType != XmlPullParser.END_DOCUMENT) {
         String name = null;

         switch (eventType){
             case XmlPullParser.START_TAG:
                 // handle open tags
                 break;
             case XmlPullParser.END_TAG:
                 // handle close tags
                 break;
         }

         eventType = parser.next();
     }
 }
 catch (XmlPullParserException e) {
     throw new RuntimeException("Cannot parse XML");
 }
 catch (IOException e) {
     throw new RuntimeException("Cannot parse XML");
 }
 finally {
     parser.close();
 }

Мое окончательное решение, которое использует синтаксический анализатор SAX для InputStream , сгенерированного из необработанного ресурса, работает. Я могу анализировать большие XML-файлы без сбоев DalvikVM:

 InputStream is = getResources().openRawResource(R.raw.index);
 XmlHandler myXMLHandler = new XmlHandler();

 SAXParserFactory spf = SAXParserFactory.newInstance();
 SAXParser sp = spf.newSAXParser();
 XMLReader xr = sp.getXMLReader();

 xr.setContentHandler(myXMLHandler);
 xr.parse(new InputSource (is));

 } catch (Exception e) {
     System.out.println("XML Pasing Excpetion = " + e);
 }

Где XmlHandler:

 public class XmlHandler extends DefaultHandler {

     @Override
     public void startElement(String uri, String localName, String qName,
     Attributes attributes) throws SAXException {
     // handle elements open
     }

     @Override
     public void endElement(String uri, String localName, String qName)
     throws SAXException {  
     // handle element close
     }

     @Override
     public void characters(char[] ch, int start, int length)
     throws SAXException {
     // handle tag characters <blah>stuff</blah>
     }

 }
2 голосов
/ 19 августа 2010

Не знаю, какова цель вашего приложения, но задумывались ли вы об использовании CSV-файла.

 InputStream is = c.getResources().openRawResource(R.raw.csv_file);
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String readLine = null;

        int column = 1; 

        try {
            while ((readLine = br.readLine()) != null) {


            }
        } catch (IOException e) {
            e.printStackTrace();
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...