Android背景服务中的领域

No *_*eto 6 android realm

我在我的android应用程序中使用Realm.我通过CompletionEvent从谷歌驱动器收到通知,所以我需要在服务中修改我的领域数据库.

我得到的例外是:

java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
Run Code Online (Sandbox Code Playgroud)

我已经在我的Application类中设置了我的默认配置:

RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(getApplicationContext())
            .deleteRealmIfMigrationNeeded()
            .build();
Realm.setDefaultConfiguration(realmConfiguration);
Run Code Online (Sandbox Code Playgroud)

在我的服务的onCreate中,我得到了我的Realm实例:

mRealm = Realm.getDefaultInstance();
Run Code Online (Sandbox Code Playgroud)

然后我在服务中使用这个领域实例:

mRealm.executeTransaction(realm -> {
        DocumentFileRealm documentFileRealm = realm.where(DocumentFileRealm.class)
                .equalTo("id", documentFileId)
                .findFirst();
        documentFileRealm.setDriveId(driveId);
    });
Run Code Online (Sandbox Code Playgroud)

但是当执行最后一个时,应用程序会启动IllegalStateException.我不知道为什么.我不确定它是否与我在Android清单中声明服务的方式有关,所以我把它留在这里:

<service android:name=".package.UploadCompletionService" android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.drive.events.HANDLE_EVENT"/>
    </intent-filter>
</service>
Run Code Online (Sandbox Code Playgroud)

可以从后台服务中调用Realm吗?我使用它的方式有什么问题?

提前致谢.

Epi*_*rce 4

在 IntentService 中,您应该像对待AsyncTask 的方法onHandleIntent一样对待该方法。doInBackground

因此它在后台线程上运行,您应该确保在finally块中关闭Realm。

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();
            }
        }
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

onCreate在 UI 线程上运行,因此 Realm 的初始化发生在不同的线程上,这是不行的。