Android: доступ к области из неправильного потока. Доступ к объектам Realm возможен только в том потоке, в котором они были созданы.

Таким образом, внутри IntentService приложение может быть активным или неактивным, вызывается onHandleIntent, где я разместил этот код ниже. Здесь я храню данные в области.

 Realm realm = null;
    try { 
        realm = Realm.getDefaultInstance();
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {

                for (AppItem item : items) {
                    AppItem item2 = realm.createObject(AppItem.class, UUID.randomUUID().toString());
                    item2.mName = item.mName;
                    item2.mCount = item.mCount;
                    item2.mUsageTime = item.mUsageTime;
                }
            }
        });
    } finally {
        if (realm != null) {
            realm.close();
        }
    }

Затем я пытаюсь получить к нему доступ в onPostExecute в AsyncTask, в doInBackground я получаю RealmResults<AppItem>, затем сохраняю его в List <AppItem> и отправляю в onPostExecute, где находится этот код. appItems здесь ReamObject

 Realm backgroundRealm = Realm.getDefaultInstance();
            backgroundRealm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    for (AppItem item : appItems) { 
 //getting error here   if (item.mUsageTime <= 0) continue;
                        mTotal += item.mUsageTime;
                        item.mCanOpen = mPackageManager.getLaunchIntentForPackage(item.mPackageName) != null;


               }
              }
            });

И то, и другое я сделал, используя executeTransactionAsync, но все равно получаю следующую ошибку.

java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.

person MrRobot9    schedule 28.05.2018    source источник


Ответы (2)


Согласно сообщению об ошибке: как только вы получите какие-либо объекты Realm в 1 потоке, к ним можно будет получить доступ ТОЛЬКО в этом потоке. Любой доступ к другим потокам вызовет это исключение.

«doInBackground» из AsyncTask запускается в фоновом потоке. «onPostExecute» запускается в потоке пользовательского интерфейса. Итак, здесь вы получаете объекты Realm в фоновом потоке и пытаетесь получить к ним доступ в потоке пользовательского интерфейса => Исключение.

Вы должны либо делать все в фоновом потоке, либо все в потоке пользовательского интерфейса.

Если вы выполняете очень сложный запрос, я предлагаю использовать «findAllAsync» в RealmQuery, так как это запустит запрос в фоновом потоке и переместит их в основной поток, но Realm обрабатывает его внутри безопасным образом. .

person Moonbloom    schedule 28.05.2018

for (AppItem item : appItems) { 

Если appItems содержит управляемые объекты RealmObject, которые вы получили из RealmResults в потоке пользовательского интерфейса, то доступ к ним в фоновом потоке завершится ошибкой.

realm.executeTransactionAsync((realm) -> { дает вам параметр Realm as, который выполняется в исполнителе потока Realm, поэтому это необходимо использовать для получения управляемых RealmResults/RealmObjects внутри транзакции.

Поэтому вам нужно повторно запросить объекты внутри realm.executeTransactionAsync, если объекты являются управляемыми.

            public void execute(Realm realm) {
                for (AppItem item : realm.where(AppItem.class).findAll()) { 
person EpicPandaForce    schedule 28.05.2018
comment
Спасибо, и я прочитал ваши блоги на Realm! они действительно хороши - person MrRobot9; 29.05.2018