JSONObject toString иногда вызывает ConcurrentModificationError

Прежде всего, извините, что не могу предоставить свой код. Я создал JSONObject и конвертирую в строку, и мое приложение для Android иногда падает со следующей ошибкой.

E/AndroidRuntime( 6162): java.util.ConcurrentModificationException
E/AndroidRuntime( 6162):    at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
E/AndroidRuntime( 6162):    at org.json.JSONArray.writeTo(JSONArray.java:612)
E/AndroidRuntime( 6162):    at org.json.JSONStringer.value(JSONStringer.java:233)
E/AndroidRuntime( 6162):    at org.json.JSONObject.writeTo(JSONObject.java:720)
E/AndroidRuntime( 6162):    at org.json.JSONObject.toString(JSONObject.java:689)

Из моего исследования я не могу сказать, почему существует ConcurrentModificationException. У меня есть только один поток, доступ к информации. Я не думаю, что toString() удаляет что-либо. Может ли кто-нибудь объяснить, видел ли он какую-либо такую ​​​​проблему в Android и как они могли ее решить?

ОТРЕДАКТИРОВАНО

Добавлен слегка измененный код по предложению @domi. Проблема постоянно видна в строке

message.put("сообщение", tempObject.toString());

private void message() {
    if (this.jsonObject == null) 
        this.jsonObject = new JSONObject();
    try {
        TimeZone tz = TimeZone.getTimeZone("UTC");
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSS'Z'", Locale.US);
        df.setTimeZone(tz);
        Date date = new Date();
        String dateString = df.format(date);
        System.out.println(dateString);
        jsonObject.put("Date", dateString);

        JSONObject jsObj = new JSONObject();
        jsObj.put("Cat", Cat.getInfo());
        jsonObject.put("Cat", jsObj);

        JSONArray tempInfo = getJsonArray(Dog.getInfo());

        jsonObject.put("Dog", tempInfo);
    } catch (JSONException e) {
        e.printStackTrace();
    }


    TimeZone tz = TimeZone.getTimeZone("UTC");
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSS'Z'", Locale.US);
    df.setTimeZone(tz);
    Date date = new Date();
    String dateString = df.format(date);

    if (this.message == null)
        this.message = new JSONObject();

    try {

        message.put("topic", topic);
        JSONObject tempObject = new JSONObject();

        synchronized(this.jsonObject) {
            System.out.println("In lock" + dateString);
            tempObject = this.jsonObject;
            this.jsonObject = null;
        }

        message.put("message", tempObject.toString());
        tempObject = null;

        synchronized (this.message) {
            doSomething(message);
        }
        System.out.println("Out lock");
    } catch (JSONException e) {
        e.printStackTrace();
    } finally {
        System.out.println(message);
    }
}

person JustLookingForAnswers    schedule 12.02.2015    source источник
comment
stackoverflow.com/questions/10690903/   -  person domi    schedule 13.02.2015
comment
Спасибо @Доми. Я не перебираю JSONObject, хотя думаю, что toString должен. Он падает внутри метода toString. toString не должен удалять какие-либо элементы.   -  person JustLookingForAnswers    schedule 13.02.2015
comment
вы действительно должны опубликовать какой-то код, небольшой фрагмент в порядке :)   -  person domi    schedule 13.02.2015


Ответы (1)


Я смог решить это. Проблема была

message.put("message", tempObject.toString());

Вызов метода tempObject.toString() приводит к итерации по списку (предположение), а message.put(...) приводит к доступу к результирующей строке. Иногда это приводит к ConcurrentModificationException. Я смог решить эту проблему, сделав это в две строки и установив несколько замков.

person JustLookingForAnswers    schedule 13.02.2015