Android: доступ к области из неверного потока.Доступ к объектам области возможен только в том потоке, в котором они были созданы. - PullRequest
0 голосов
/ 29 мая 2018

Таким образом, внутри 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.

Ответы [ 2 ]

0 голосов
/ 29 мая 2018
for (AppItem item : appItems) { 

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

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

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

            public void execute(Realm realm) {
                for (AppItem item : realm.where(AppItem.class).findAll()) { 
0 голосов
/ 29 мая 2018

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...