gson reader out of memory string builder错误

时间:2014-03-06 19:45:00

标签: android json string memory gson

我正在使用gson阅读器来读取json对象数组,从中获取我想要的值并创建更小的对象。

对于我测试的大多数json文件,一切正常,但有一个给我以下logcat错误:

03-06 13:13:35.859: E/AndroidRuntime(3025): FATAL EXCEPTION: AsyncTask #2
03-06 13:13:35.859: E/AndroidRuntime(3025): java.lang.RuntimeException: An error occured while executing doInBackground()
03-06 13:13:35.859: E/AndroidRuntime(3025):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.lang.Thread.run(Thread.java:856)
03-06 13:13:35.859: E/AndroidRuntime(3025): Caused by: java.lang.OutOfMemoryError
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:124)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.lang.StringBuilder.append(StringBuilder.java:271)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at com.google.gson.stream.JsonReader.nextQuotedValue(JsonReader.java:988)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at com.google.gson.stream.JsonReader.nextString(JsonReader.java:811)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at example.myapp.LoadFileFragment.getTwo(LoadFileFragment.java:676)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at example.myapp.LoadFileFragment.getInfo(LoadFileFragment.java:618)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at example.myapp.LoadFileFragment.access$1(LoadFileFragment.java:525)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at example.myapp.LoadFileFragment$DownloadTask.doInBackground(LoadFileFragment.java:184)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at example.myapp.LoadFileFragment$DownloadTask.doInBackground(LoadFileFragment.java:1)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
03-06 13:13:35.859: E/AndroidRuntime(3025):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
03-06 13:13:35.859: E/AndroidRuntime(3025):     ... 5 more

这是失败的方法,它基本上检查嵌套对象中的一个键是否有值,如果是,则获取字符串,检查同一对象中的另一个键是否有值以及是否有值在返回之前将它们加在一起。

private String getTwo(JsonReader reader, String n1, String n2) throws IOException{
            String str="";
            String str1="";
            String str2="";
               reader.beginObject();
               while (reader.hasNext()) {
                   str=""; 
                   String nm = reader.nextName(); 
                   if(nm.equals(n1)&& reader.peek() != JsonToken.NULL){
                       str1=reader.nextString();
                       }
                   else if(nm.equals(n2)&& reader.peek() != JsonToken.NULL){
                       str2=" "+reader.nextString();
                        } 
                   else {
                         reader.skipValue();
                       }
           }
        str=str1+str2;
       return str;
        }

逻辑是合理的 - 它适用于我测试的数千个其他对象。每次遇到一个字符串长度约为1300个字符的特定对象时,我都会收到此错误 - 问题是什么?如果是这样,是否有某种方法可以预先进行长度检查,并可能将字符串分开?或者有更好的方法来做这件事吗?我尝试使用StringBuilder,但在同一个对象上遇到了同样的错误。

一个非常奇怪的事情是我只在平板电脑上运行错误(运行ICS) - 在我的手机上(运行姜饼)它工作正常

更新

所以,这是我能想到的最少记忆消耗的方式:

StringBuilder strb=new StringBuilder();

    private String getTwo(JsonReader reader, String n1, String n2) throws IOException{
        strb.setLength(0);
        strb.append("");
        reader.beginObject();
           while (reader.hasNext()) {
               String nm = reader.nextName(); 
               if(nm.equals(n1)&& reader.peek() != JsonToken.NULL){
                   strb.append(reader.nextString());
                   }
               else if(nm.equals(n2)&& reader.peek() != JsonToken.NULL){
                   strb.append(reader.nextString());
                    } 
               else {
                     reader.skipValue();
                   }
       }

   return strb.toString();
    }

但它仍然在完全相同的位置崩溃......它不能是字符串的长度(据我所知,1300个字符相对来说没什么),但我确实注意到有问题的字符串有各种各样的字符串其中的HTML标签。其他带有html标签的较短字符串似乎不会造成问题,所以它似乎是长度和标签的组合。这unresolved post似乎正处理一个非常类似的问题......有什么想法吗?

0 个答案:

没有答案