2016-08-07 4 views
0

Итак, я создал очень стандартный адаптер синхронизации (с использованием this fantastic tutorial) и в течение onPerformSync Я запустил некоторые транзакции в области с помощью метода syncDatastore в пределах моего класса DataManager. Проблема заключается в том, когда адаптер синхронизации пытается выполнить синхронизацию, я получаюОшибка правильного потока в Realm от SyncAdapter

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

Я инициализировать 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); 
    } 
} 

Обратите внимание, что я попытался удалить android:process=":sync" из моей декларации сервиса в манифест as outlined here, но безрезультатно. Я также совершенно новичок как для SyncAdapters, так и для Realm, поэтому любая помощь будет оценена по достоинству.

+0

Где экземпляр Realm, используемый в этой строке 'clients.addAll (realm.where (Client.class) .equalTo ("isSynced", ложь) .equalTo ("apiId", "0"). FindAll()), 'от? Где он инициализируется? – EpicPandaForce

+0

См. Мое редактирование в 'DataManager' –

+0

oh, и ваш DataManager создается вместе с приложением в какой-то момент, поэтому принадлежащее ему Realm находится в потоке пользовательского интерфейса. Имеет смысл. Это не сработает. – EpicPandaForce

ответ

2

Реальные экземпляры объектов ограничены потоками, поэтому вам нужен новый экземпляр 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); 
    } 
} 
+0

Спасибо за ответ. К сожалению, используя этот код, вы получите 'java.lang.IllegalStateException: этот экземпляр Realm уже закрыт, что делает его непригодным' при вызове' realm.beginTransaction() 'в других методах в DataManager' –

+0

. Следует также упомянуть, что DataManager одноэлементный класс. Но я не думаю, что это будет иметь значение. –

+0

.... нет, Королевство не должно закрываться, пока вы его не закроете. – EpicPandaForce

Смежные вопросы