2016-05-06 7 views
6

Przeczytałem wiele postów dotyczących tego tematu, ale wciąż jest to dla mnie trochę niejasne. Rozumiem, że nie można uzyskać dostępu do obiektów klasy lub obszaru rzeczywistego w różnych wątkach, więc zastanawiam się, jaki jest optymalny sposób na obsłużenie tego.Dostęp do obszaru przez wątki z rxjava i dagger2

Mam usługę, która uruchamia wątek. Wątek ten działa w tle (w tym działa przez rxjava na Schedulers.io). Teraz w pewnym momencie chcę zapisać niektóre dane do sfery, która żyje w klasie DataManager. Pierwotnie używałem Dagger2 do wstrzyknięcia Realm do mojej klasy DataManager (która sama została wstrzyknięta do usługi). Jednak to nie zadziała, ponieważ wtrysk został wykonany na głównym wątku, więc Realm.getDefaultInstance() jest związany z głównym wątkiem, ale jest dostępny w DataManager z innego wątku.

Jedyną opcją feasiblbe, o której mogę pomyśleć, to wywołanie Realm.getDefaultInstance() i realm.close() na początku i na końcu każdej metody przeprowadzania transakcji. Nie mam nic przeciwko temu, ale zastanawiam się, czy wystąpi wydajność, dzwoniąc pod numer Realm.getDefaultInstance() za każdym razem, gdy chcę zapisać obiekt. Czy jest lepszy sposób to zrobić? Z góry dziękuję.

+0

'Realm.getDefaultInstance()' będzie nieco powolne, jeśli jest to pierwsze wystąpienie wśród wszystkich wątków. W przeciwnym razie zwraca się natychmiast, ponieważ Realm buforuje schematy wewnętrznie. Zobacz https://github.com/realm/realm-java/issues/2231 – beeender

+0

FYI Zdecydowałem się porzucić Realm dla mojego konkretnego przypadku użycia. Zasadniczo potrzebowałem zrobić 'copyFromRealm' na wszystkich moich przyniesionych obiektach, tak że mogłem przekazać je przez wątki, a wtedy korzyści z obiektu na żywo były prawie na wyciągnięcie ręki. Było to również farbą do zarządzania zamykaniem instancji w klasach pomocników. Jestem pewien, że jest lepszy sposób, aby sobie z tym poradzić, ale zdecydowałem się trzymać z sqlite i orm. – pat

Odpowiedz

0

I rozwiązać ten problem podczas korzystania z wątków Realm w jednej z moich aplikacji tworząc DatabaseManager klasę którą wstrzykuje się działań i usług przy użyciu Dagger 2.

Tak na przykład, jeśli mam podmiot Task klasa DatabaseManager miał metodę void update(Task task), która uzyskałaby domyślną instancję Realm, pobierze Task z danym ID z bazy danych Realm, zaktualizuje otrzymaną instancję Task w bloku transakcji, wykona realm.copyFromRealm(updatedTask); i zamknie instancję Realm na końcu metody.

Realm realm = Realm.getDefaultInstance(); 
     realm.executeTransaction(new Realm.Transaction() { 
      @Override 
      public void execute(Realm realm) { 
       // fetch the object from Realm database and update it as required. 

       //https://realm.io/docs/java/latest/api/io/realm/Realm.html#copyFromRealm-E- 
       // Makes an unmanaged in-memory copy of an already persisted RealmObject. 
       realm.copyFromRealm(task); 

       } 
      } 
     }); 
realm.close(); 

To zadziałało dla mnie. Jeśli jest lepsze podejście, chciałbym wiedzieć więcej.