Сериализация ANdroid вызывает исключение ConcurrentModificationException.Как я могу избежать этого? - PullRequest
0 голосов
/ 02 июня 2011

При сериализации моего объекта, который представляет собой пользовательский класс, содержащий различные списки ArrayLists, очень часто я получаю исключение для одновременного мод.Ясно, что один или несколько arraylists бросают это.Но я не знаю, где и как это исправить.Реализация итератора была бы моей первой идеей, но как это сделать для сериализации?

Это мой код сериализации: enter code here

 try{
    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 

    try { 
          ObjectOutput out = new ObjectOutputStream(bos); 
          out.writeObject(TGame);

          // Get the bytes of the serialized object 
          byte[] buf = bos.toByteArray(); 

          File sdCard = Environment.getExternalStorageDirectory();
          File dir = new File (sdCard.getAbsolutePath() + "/game_folder");
          dir.mkdirs();
          File file = new File(dir, "serializationtest");


          FileOutputStream fos = new FileOutputStream(file);
              //this.openFileOutput(filename, Context.MODE_PRIVATE);
          fos.write(buf);
          fos.close(); 
        } catch(IOException ioe) { 
          Log.e("serializeObject", "error", ioe); 


        }catch(StackOverflowError e){
            //do something
        }

        File f =this.getDir(filename, 0);
        Log.v("FILE SAVED",f.getName());    
    }catch(ConcurrentModificationException e){
        //do something          
    }
}

1 Ответ

0 голосов
/ 05 сентября 2011

Пока Java api сериализует объект (здесь список внутренних массивов), если в то же время какой-то другой поток структурно изменяет ArrayList, вы получаете исключение одновременной модификации.

Одним из решений является механизм блокировки, обеспечивающий доступ только одного потока к этому объекту за раз. Другое простое решение состоит в том, что объект, который должен быть записан, создает поверхностную копию этого объекта и сериализует эту копию. Таким образом, даже если оригинальный ArrayList изменится, поверхностное копирование не будет иметь эффекта и будет работать нормально. например,

class Test {
 int a;
 string b;
 ArrayList<String> c;
 Test(Test t){
  this.a=t.a;
  this.b=t.b;
  this.c=new ArrayList<String>(t.c);
 }
}
FileOutputStream fos = new FileOutputStream(file);
//write a copy of original object
      fos.write(new Test(t));

}
...