java - 来自 SyncAdapter 的 Realm 不正确线程错误

标签 java android multithreading realm android-syncadapter

因此,我创建了一个非常标准的同步适配器(使用 this fantastic tutorial ),并且在 onPerformSync 期间,我在 内的名为 syncDatastore 的方法中运行一些 Realm 事务DataManager 类。问题是当同步适配器尝试执行同步时,我得到

java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.

这是我的 SyncAdapter 的摘录:

@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
    try {
        // Get the auth token for the current account
        String authToken = _accountManager.blockingGetAuthToken(account, AccountGeneral.AUTHTOKEN_TYPE_FULL_ACCESS, true);

        // run network and database operations
        dataManager.syncDatastore();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

我使用以下方法初始化 Application 类中的 RealmConfiguration:

RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(this).build();
Realm.setDefaultConfiguration(realmConfiguration);

以及如何在我的 DataManager 中使用它的示例:

private Realm realm = Realm.getDefaultInstance();

public void syncDatastore() {
    postResources();
    pushDataToServer();
    getDataFromServer();
}

private void postResources() {
    ArrayList<Client> clients = new ArrayList<>();
    clients.addAll(realm.where(Client.class).equalTo("isSynced", false).equalTo("apiId", "0").findAll());
    Log.e("clients count", String.valueOf(clients.size()));
    for (Client c : clients) {
        createClientResource(c);
    }
}

请注意,我已尝试从 list as outlined here 中的服务声明中删除 android:process=":sync"但无济于事。我对 SyncAdapters 和 Realm 也很陌生,因此我们将不胜感激。

最佳答案

Realm 实例受线程限制,因此您需要在后台线程(发生同步的后台线程)上创建一个新的 Realm 实例。

@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
    Realm realm = null;
    try {
        realm = Realm.getDefaultInstance();
        // Get the auth token for the current account
        String authToken = _accountManager.blockingGetAuthToken(account, AccountGeneral.AUTHTOKEN_TYPE_FULL_ACCESS, true);

        // run network and database operations
        dataManager.syncDatastore(realm);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if(realm != null) {
            realm.close();
        }
    }
}

public void syncDatastore(Realm realm) {
    postResources(realm);
    pushDataToServer();
    getDataFromServer();
}

private void postResources(Realm realm) {
    RealmResults<Client> clients = realm.where(Client.class).equalTo("isSynced", false).equalTo("apiId", "0").findAll();
    Log.e("clients count", String.valueOf(clients.size()));
    for (Client c : clients) {
        createClientResource(c);
    }
}

关于java - 来自 SyncAdapter 的 Realm 不正确线程错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38817218/

相关文章:

java - 如何确保首先调用 Spring @EventListener?

android - React Native 中的状态栏颜色

javascript - 我是否需要在 cordova/phonegap 项目的所有 html 文件中添加 app.initialize()

android - 为工作区中的每个项目创建 ant build.xml 文件

c# - 为什么需要冗余锁对象?

ios - 如何 "visualize"(观察)iOS 中退出的线程?

java - 如何在所有 Java 类中使用 RabbitTemplate

java - 将任意转义字符转换为 int

多线程 - 一组中所有对之间的计算

java - 如何在Android 2.1+实现圆角标签