来自SyncAdapter的Realm错误的线程错误

时间:2016-08-07 18:26:08

标签: java android multithreading realm android-syncadapter

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

  

java.lang.IllegalStateException:从错误的线程访问Realm。   Realm对象只能在创建它们的线程上访问。

以下是我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);
    }
}

请注意我已尝试从清单as outlined here中的服务声明中删除android:process=":sync",但无济于事。我对SyncAdapter和Realm都很陌生,所以任何帮助都会受到最高的赞赏。

1 个答案:

答案 0 :(得分:2)

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);
    }
}