0

I'm using the gson reader to read through an array of json objects, get the values that I want out of them and create smaller objects.

Everything works fine for most json files that I have tested, but there is one that gives me the following logcat error:

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

Here is the method that is failing, which basically checks to see if one key within a nested object has a value, gets the string if it does, checks to see if another key within the same object has a value and if it does adds them together before returning.

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

The logic is sound - it works on thousands of other objects I have tested. I get this error every time when it comes to one particular object that has a string that is about 1300 chars long - is that the problem? And if so, is there some way of doing a length check beforehand and maybe splitting the string up? Or is there some better way to be doing this? I tried using StringBuilder, but got the same error on the same object.

One very strange thing is that I only get the error on my tablet (running ICS) - on my phone (running gingerbread) it works fine

UPDATE

So, this is the least memory-consumptive way I can think of doing this:

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

but it still crashes in exactly the same spot... It can't be the length of the string (1300 characters is relatively nothing as far as I can tell), but I did notice that the string in question has various html tags in it. Other, shorter strings with html tags don't seems to pose a problem, so it seems to be a combination of length and tags. This unresolved post seems to be dealing with a very similar issue... Any thoughts?

Community
  • 1
  • 1
lucas
  • 1,485
  • 13
  • 22
  • 2
    How about using a StringBuilder? See http://stackoverflow.com/questions/73883/string-vs-stringbuilder – donfuxx Mar 06 '14 at 19:49
  • You should read about strings being immutable, then consider an alternative approach. You do understand that each time you execute `str=""`, you are creating a new string. – Simon Mar 06 '14 at 19:49
  • @Simon: yes, I think I do understand that. Any suggestions on the alternative approach? I did try StringBuilder but came up against the same problem - maybe a bad implementation? – lucas Mar 06 '14 at 20:08
  • Did you try checking to make sure the json you are parsing is valid? https://jsonlint.com/ – bryce Oct 09 '17 at 23:26

0 Answers0