2016-08-07 8 views
0

非常に標準の同期アダプタ(this fantastic tutorialを使用)を作成し、onPerformSyncの中でDataManagerクラス内のsyncDatastoreというメソッドで領域トランザクションを実行します。問題は、同期アダプタが同期を実行しようとしたときです。RealAdのSyncAdapterからの不正なスレッドエラー

java.lang.IllegalStateException:不正なスレッドからのレルムアクセスです。 レルムオブジェクトは、作成されたスレッドでのみアクセスできます。ここで

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"を削除しようとしましたが、役に立たないことに注意してください。私はSyncAdaptersとRealmの両方にも非常に新しいので、どんな助けでも大歓迎です。

+0

。のfindAll ());「元気?それはどこで初期化されますか? – EpicPandaForce

+0

「DataManager」 –

+0

で私の編集を見てください。あなたのDataManagerはある時点でアプリケーションとともにインスタンス化されます。そのため、それに属するレルムはUIスレッド上にあります。意味をなさないそれは動作しません。 – EpicPandaForce

答えて

2

レルムインスタンスはスレッド制限されているため、バックグラウンドスレッド(同期が行われているバックグラウンドスレッド)に新しいRealmインスタンスが必要です。このライン `clients.addAll(realm.where(Client.class).equalTo( "isSynced"、false)を.equalTo( "apiId"、 "0")で使用されるレルムインスタンスを行い

@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); 
    } 
} 
+0

お返事ありがとうございます。残念なことに、このコードを使用すると 'java.lang.IllegalStateException:このRealmインスタンスは既に閉じられているため、' DataManager'の他のメソッドで 'realm.beginTransaction()'を呼び出すとエラーが発生します。 –

+0

DataManagerはシングルトンクラス。しかし、私はそれが何か変わるとは思わない。 –

+0

....いいえ、Realmは実際に閉じるまで閉じてはいけません。 – EpicPandaForce

関連する問題