【问题标题】:Should I be using something other than getResource().getStringArray() to populate a large array?我应该使用 getResource().getStringArray() 以外的东西来填充一个大数组吗?
【发布时间】:2010-08-19 13:20:53
【问题描述】:

按照 Android sample for populating a ListView,我使用 Activity.getResource().getStringArray() 从我的 strings.xml 中查询一个数组:

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

这个方法的文档很清楚,我没想到会遇到任何问题:

返回与特定资源 ID 关联的字符串数组。

这种方法对小型数据集按预期工作。但是,当我用完整的数据集(接近 2000 个条目)填充 strings.xml 时,我发现应用程序在尝试加载资源时崩溃了。我在控制台日志中注意到了这个错误:

参考表溢出(最大值=512)

玩弄我的 string-array 中的项目数,我确认当项目数超过 ~700 个条目时,该错误是可重现的。

谷歌搜索该问题已经找到了其他开发人员having the same problem 的一些示例,但我在 Android 文档中找不到任何解释它的内容。

有人费力在 Android Google 代码页面上创建了一个issue for the problem,但它或我遇到的任何帖子都没有得到满意的答案。

我是否以错误的方式解决问题?我是否应该自己填充数据(加载文件并解析 JSON 或类似内容)并完全避免该问题?感觉好像我在这里遗漏了一些明显的东西。

【问题讨论】:

    标签: android


    【解决方案1】:

    我需要能够为我的特定应用程序解析大型 XML 文件(我已经有以这种方式编码的数据,我希望保持它的一致性)。

    所以我的第一次尝试是使用getStringArray,它遇到了问题中描述的问题:

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

    我的第二次尝试遇到了与 getStringArray 相同的限制。当我尝试处理更大的 XML 文件 (> 500K) 时,我在 getXml 上遇到了 DalvikVM 崩溃:

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

    我的最终解决方案是在从原始资源生成的 InputStream 上使用 SAX 解析器。我可以在 DalvikVM 不崩溃的情况下解析大型 XML 文件:

     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】:

      不确定您的应用程序的目标是什么,但您是否考虑过使用 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();
              }
      

      【讨论】:

      • @sameersegal 所以我猜你的答案是“是的,你应该自己加载数据并完全避免这个问题”;)。我当然倾向于这个方向。但是,我确实想知道为什么文档对这个问题如此沉默。
      猜你喜欢
      • 2013-07-26
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-13
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      相关资源
      最近更新 更多