-3

I am using Realm as my Database. And while inserting/updating the data I am getting the following error

FATAL EXCEPTION: main
Process: uk.org.humanfocus.hfi, PID: 6430
 java.util.ConcurrentModificationException
 at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
  at org.json.JSONArray.writeTo(JSONArray.java:612)
  at org.json.JSONStringer.value(JSONStringer.java:233)
  at org.json.JSONObject.writeTo(JSONObject.java:720)
  at org.json.JSONObject.toString(JSONObject.java:689)
  at uk.org.humanfocus.hfi.DriverBehavior.DriverBehaviorMap$InsertCarProbeData.onPostExecute(DriverBehaviorMap.java:252)
  at uk.org.humanfocus.hfi.DriverBehavior.DriverBehaviorMap$InsertCarProbeData.onPostExecute(DriverBehaviorMap.java:229)
  at android.os.AsyncTask.finish(AsyncTask.java:651)
  at android.os.AsyncTask.-wrap1(AsyncTask.java)
  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
  at android.os.Handler.dispatchMessage(Handler.java:102)
  at android.os.Looper.loop(Looper.java:148)
  at android.app.ActivityThread.main(ActivityThread.java:5443)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

Unlike others I am not doing it in the for loop, instead I am doing it in the onPostExecute method of AsyncTask which is called from location changed listener. Neither is it being used somewhere else.

private class InsertCarProbeData extends AsyncTask<Void, Void, Void> {

    Location location;

    public InsertCarProbeData(Location location) {
        this.location = location;
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            addObjectToJSONArray(location);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        realm.beginTransaction();
        trip.json = tripJSON.toString();
        realm.commitTransaction();
    }
}

And this AsyncTask is being called from here

new InsertCarProbeData(location).execute();
Salmaan
  • 3,543
  • 8
  • 33
  • 59
  • Dear Downvoter, In case of down votes please comment the reason so I can avoid my mistake in future. – Salmaan Nov 21 '16 at 11:19
  • Without knowladge about addObjectToJSONArray I bet that `tripJSON.toString()` is called at the same time as `addObjectToJSONArray(location);` (which on 99% modyfing `tripJSON`) – Selvin Nov 21 '16 at 11:19
  • 1
    And about downvote: I bet that [this](http://stackoverflow.com/help/how-to-ask) may help ... and [this](http://stackoverflow.com/help/mcve) – Selvin Nov 21 '16 at 11:23
  • @Selvin addObjectToJSONArray(location); is called from doInBackground and tripJSON.toString() is called from onPostExecute. Arent it supposed to be called after the change has taken place? – Salmaan Nov 21 '16 at 11:26
  • What version of Realm are you using? – EpicPandaForce Nov 21 '16 at 11:26
  • *Arent it supposed to be called after the change has taken place?* Yes ... and? It is obvious ... you just create and execute new async task when old one was in "`onPostExecute` state" ... it's multithreading ... – Selvin Nov 21 '16 at 11:28
  • @EpicPandaForce 2.0.2 It seems that if I do it in background thread, it may fix this issue – Salmaan Nov 21 '16 at 11:32
  • 1
    **BTW** the downvotes are because obviously the offending line is `tripJSON.toString();`, but where `tripJSON` is initialized is unknown, and so is `addObjectToJSONArray`. – EpicPandaForce Nov 21 '16 at 11:36

1 Answers1

1

There is several problens in your code:

1) you store all values inside JSONArray, that means, it will attempt to wtite ALL PREVIOUS values too. When array grow large, new data arraive while old values is still bein processed - that is reason of error

2) .onPostExecute() method is executed on main thread, so by doing so, you have no benefit of AsyncTask.

3) AsyncTask is obsolete and is shares the same thread pool (with the same proirity, as main thread)

There is similar answer, look into it: Writing realm from service class causing UI block

Community
  • 1
  • 1
Alex Shutov
  • 3,217
  • 2
  • 13
  • 11