2017-01-20 8 views
1

私は、まずデータをキャッシュからダウンロードし、サーバAPIからデータを要求し、その結果を保存し、ネットワークデータから与えられたデータをプレゼンタ(MVP) 。RxJava 2とIOスレッドでRealmと連携する

Realmでの作業は、UIスレッドでバックグラウンドで作業したい場合に発生します。最初のRxJavaの領域サポートについての記事をいくつか見つけましたが、別のAPIを持つ2番目のバージョンを使用しているため、これらの領域メソッドは私たち(toObservable())には役に立ちません。

この問題を解決するにはどうすればよいですか?

さらに、他のすべてのメソッドはIOスレッドで処理され、という事実にかかわらず、RealmだけがUiで動作します。それはなぜ起こるのですか?まあ

@Override 
public Observable<ChatsRepoAnswerModel> getChats() { 
    return getChatsFromCache(STATUS_OK) 
      .subscribeOn(Schedulers.io()) 
      .mergeWith(
        getChatsService() 
          .getChats() 
          .subscribeOn(Schedulers.io()) 
          .map(ChatResponseModel::getResult) 
          .flatMap(mChatsMapper::transformAll) 
          .doOnNext(this::saveChats) 
          .doOnNext(Collections::sort)        
          .onErrorResumeNext(getChatsFromCache(STATUS_ERROR))        
      .observeOn(AndroidSchedulers.mainThread()); 
} 


private void saveChats(List<ChatDataModel> realmObjects) {   
    Realm.getDefaultInstance().executeTransaction(realm -> { 
     realm.insertOrUpdate(realmObjects); 
    }); 
} 

private Observable<ChatsRepoAnswerModel> getChatsFromCache(int aStatus) { 
    Realm realm = Realm.getDefaultInstance(); 
    RealmResults<ChatDataModel> chats = realm.where(ChatDataModel.class).findAll(); 
    return processChatResponse(realm.copyFromRealm(chats), aStatus); 
} 
+1

レルムが提供する観測可能なデータセットを観察しているはずなので、この問題が発生しています。 [無作為のネットワークデータを送信し、反応ゼロコピー遅延評価主導型データベースからすべての要素を切り離して熱心にコピーしようとするのではなく](https://medium.com/@Zhuinden/すべてのクエリは、スレッドを使用したスレッドを使用してオブジェクトを分離する方法をプロフェッショナルに悪用します(realm-and-56683dbdeaf9)。 – EpicPandaForce

+0

いくつかの説明リンクを追加できますか?なぜ私はsubscribeOn追加のスレッドとこれはレルムで動作しません他のメソッドを使用することはできますか? – Gaket

+0

UIスレッドにバインドされたRealmインスタンスからバックグラウンドスレッドを読み取ろうとしているためです。しかし、私はこの物に関する記事を追加しました。恐らく、あなたがRealmインスタンスを閉じていないのに、 – EpicPandaForce

答えて

1

私はこのあなたを与えるためにしようとしているものレルムのゼロコピーデザインのための完全な無視であると考えている間:

  • 自動更新からの一方向のデータフローとRealmResults
  • レイジー評価を(データが変更を設定したときに通知され意味する)、要素のみの交流の形でレルムによって提供さ反応データセット読んでいる時にcessed、RealmResultsは単に「カーソル」であり、RealmObject sがアクセサが
  • 一貫と呼ばれている場合にのみ、データを読む:あなたが持っていないので、すべての管理対象RealmProxiesは外」、同じオブジェクトを指しrealm.copyFromRealm()は、一般的に、これらのいずれかを持っていない管理対象外のオブジェクトを作成するための日付」どこでも(まあ、別に保持し得る非の自動更新のバックグラウンドスレッドから、それは一般的に、ユーザー・エラーです)データ

はそれは面白いですプロパティ:

  • もはや自動更新
  • は熱心にフィールド必ずしもすべての場所で最新の状態に使用されていない結果として
  • 、と全体の設定データをコピーするすべてのデータを評価

とにかく、バックグラウンドスレッドで分離されたRealmObjectsを作成する方法は、そのスレッドでインスタンスを開き、データセットをコピーしてインスタンスを閉じることです。

Observable.fromCallable(() -> { // <-- defer to whatever thread you're running it on 
     try(Realm realm = Realm.getDefaultInstance()) { 
      return realm.copyFromRealm(realm.where(Cat.class).findAll()); 
     } // <-- auto-close 
    }) 
.subscribeOn(Schedulers.whatever()); 

通常、大規模なデータセットの場合は、意図的にRealmを使用する方が簡単です。

関連する問題