I am using Realm in my android application.I am receiving a notification from google drive via CompletionEvent so I need to modify my realm database in a service.
The exception I get is:
java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
I have set my default configuration in my Application class the next way:
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(getApplicationContext())
.deleteRealmIfMigrationNeeded()
.build();
Realm.setDefaultConfiguration(realmConfiguration);
And in the onCreate from my service I am getting my Realm instance like this:
mRealm = Realm.getDefaultInstance();
And then I use this realm instance in the service:
mRealm.executeTransaction(realm -> {
DocumentFileRealm documentFileRealm = realm.where(DocumentFileRealm.class)
.equalTo("id", documentFileId)
.findFirst();
documentFileRealm.setDriveId(driveId);
});
But when executing this last one the app launches the IllegalStateException. I don't know why. I am not sure if it has something to do with the way I have declared the service in my android manifest so I leave it here:
<service android:name=".package.UploadCompletionService" android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.drive.events.HANDLE_EVENT"/>
</intent-filter>
</service>
Is it possible calling Realm from a background service? What is wrong with the way I am using this?
Thanks in advance.
In an IntentService, you're supposed to treat the onHandleIntent
method like the doInBackground
method of an AsyncTask.
So it runs on the background thread and you should make sure you close the Realm in a finally block.
public class PollingService extends IntentService {
@Override
public void onHandleIntent(Intent intent) {
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
// go do some network calls/etc and get some data
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.createAllFromJson(Customer.class, customerApi.getCustomers()); // Save a bunch of new Customer objects
}
});
} finally {
if(realm != null) {
realm.close();
}
}
}
// ...
}
onCreate
runs on the UI thread, so your initialization of the Realm happens on a different thread, which is a no-go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With