Mukesh
Mukesh

Reputation: 33

Multiple Realm transactions causing UI thread to freeze

I am retrieving data from a server as a JSON file and then I am trying to create a Realm object for each activity.

public void onResponse(JSONObject response) {
try {
    JSONArray activities = response.getJSONArray("activities");
    Realm realm = Realm.getDefaultInstance();
    int numOfActivities = activities.length();
    for(int i = 0; i < numOfActivities; i++) {
        JSONObject activity = activities.getJSONObject(i);
        realm.beginTransaction();
        RunSummaryObject curr = realm.createObject(RunSummaryObject.class);
        try {
            curr.setId(activity.getLong("id"));
            realm.commitTransaction();
        } catch (io.realm.exceptions.RealmPrimaryKeyConstraintException e) {
            realm.cancelTransaction();
        }
    }
    realm.close();
} catch (JSONException e) {
    e.printStackTrace();
}

The code is run inside a new thread instantiated as an android AsyncTask.

private class syncRunData extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... voids) {
        downloadRunData();
        return null;
    }
}

The UI thread freeze with less than 70 activities. The same code does not freeze if I run it twice since all the objects already exists in Realm so no transaction is committed. How can I avoid freezing the UI thread?

Upvotes: 3

Views: 1249

Answers (1)

Thomas Goyne
Thomas Goyne

Reputation: 8138

You should not be performing a write transaction within the loop, as there is a nontrivial amount of per-transaction overhead. By itself this should not block the UI thread, but if you have any notification listeners on the UI thread then they will be getting called 70 times, which could potentially cause problems. Something like the following will perform much better:

public void onResponse(JSONObject response) {
try {
    JSONArray activities = response.getJSONArray("activities");
    Realm realm = Realm.getDefaultInstance();
    realm.beginTransaction();
    int numOfActivities = activities.length();
    for(int i = 0; i < numOfActivities; i++) {
        JSONObject activity = activities.getJSONObject(i);
        long id = activity.getLong("id");
        if (realm.where(RunSummaryObject.class).equalTo("id", long).findFirst() == null) {
            RunSummaryObject curr = realm.createObject(RunSummaryObject.class);
            curr.setId(activity.getLong("id"));
        }
    }
    realm.commitTransaction();
    realm.close();
} catch (JSONException e) {
    e.printStackTrace();
}

Upvotes: 1

Related Questions