2

所以在 aIntentService中,应用程序可能是活动的或非活动的,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();
        }
    }

然后我试图在onPostExecutein 中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.
4

2 回答 2

7

根据错误消息:一旦您在 1 个线程上获得任何 Realm 对象,它们只能在该线程上访问。对其他线程的任何访问都会引发该异常。

AsyncTask 中的“doInBackground”在后台线程上运行。“onPostExecute”在 UI 线程上运行。所以在这里你在后台线程上获取 Realm 对象,并尝试在 UI 线程上访问它们 => Exception。

您应该在后台线程上做所有事情,或者在 UI 线程上做所有事情。

如果您正在执行非常复杂的查询,我建议在 RealmQuery 上使用“findAllAsync”,因为这将在后台线程上运行查询,并将它们移动到主线程,但它由 Realm 在内部以安全的方式处理.

于 2018-05-28T22:17:26.107 回答
2
for (AppItem item : appItems) { 

如果appItems包含您从 UI 线程上的 RealmResults 获得的托管 RealmObjects,则在后台线程上访问它们将失败。

realm.executeTransactionAsync((realm) -> {为您提供一个 Realm 作为在 Realm 的线程执行程序上运行的参数,因此必须使用它来获取事务内的托管 RealmResults/RealmObjects。

realm.executeTransactionAsync所以如果对象是托管的,则需要重新查询里面的对象。

            public void execute(Realm realm) {
                for (AppItem item : realm.where(AppItem.class).findAll()) { 
于 2018-05-28T23:18:13.630 回答