问题
So inside a IntentService
, the app maybe active or inactive , onHandleIntent
gets called , where I have placed this below code.This is where I store the data into realm.
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();
}
}
Then I am trying to access it in onPostExecute
in AsyncTask
, In doInBackground
, I am getting the RealmResults<AppItem>
, then storing it into List <AppItem>
and sending it to onPostExecute
where this code is placed. appItems
is ReamObject here
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;
}
}
});
Both I have done using executeTransactionAsync
, still I get the following error.
java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
回答1:
As per the error message: Once you obtain any Realm objects on 1 thread, they can ONLY be accessed on that thread. Any access on other threads will throw that exception.
"doInBackground" from AsyncTask is run on a background thread. "onPostExecute" is run on the UI thread. So here you get Realm objects on a background thread, and try to access them on the UI thread => Exception.
You should either do everything on the background thread, or everything on the UI thread.
If you're doing a very complex query, i suggest using "findAllAsync" on the RealmQuery, as this will run the query on a background thread, and move them over to the main thread, but it's handled internally by Realm in a safe manner.
回答2:
for (AppItem item : appItems) {
If appItems
contains managed RealmObjects that you obtained from a RealmResults on the UI thread, then accessing them will fail on the background thread.
realm.executeTransactionAsync((realm) -> {
gives you a Realm as parameter that is running on Realm's thread executor, so that must be used to obtain managed RealmResults/RealmObjects inside the transaction.
So you need to re-query the objects inside realm.executeTransactionAsync
if the objects are managed.
public void execute(Realm realm) {
for (AppItem item : realm.where(AppItem.class).findAll()) {
来源:https://stackoverflow.com/questions/50573802/android-realm-access-from-incorrect-thread-realm-objects-can-only-be-accessed