2016-08-16 6 views
1

rxJavaを使用してデータベースからデータを取得し、それをrecyclerviewに表示します。関連するコードはrxJava Observer.onNextが2回目に呼び出されない

function updateUI(){ 
    ContactsLab contactsLab = ContactsLab.get(getActivity()); 
    Subscription sub = contactsLab.getContactList().subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .toList() 
      .subscribe(onContactsReceived()); 
    mCompositeSubscription.add(sub); 
} 

ContactsLab下に示されている連絡先オブジェクトの観測を返すシングルトンです。 onContactsReceived機能は

private Observer<List<Contact>> onContactsReceived(){ 
    return new Observer<List<Contact>>() { 
     @Override 
     public void onCompleted() {} 

     @Override 
     public void onError(Throwable e) {} 

     @Override 
     public void onNext(List<Contact> contacts) { 
      if(mContactsAdapter == null) { 
       mContactsAdapter = new ContactsAdapter(contacts); 
       mRecyclerView.setAdapter(mContactsAdapter); 
      } else{ 
       mContactsAdapter.setContactList(contacts); 
       mContactsAdapter.notifyDataSetChanged(); 
      } 
     } 
    }; 
} 

updateUI機能が私のフラグメントonResumeに呼ばれているの下に表示されますが、ビューは、初回のみ更新されます。他のフラグメント(dbに項目を追加したもの)からこのフラグメントに戻った場合、onResumeが呼び出され、updateUIが実行され、onContactsReceivedも実行されますが、onNextまたはonCompleteを呼び出さずにすぐに戻ります。

これは、rxJavaがobservablesを処理する方法と関係がありますが、それを修正する方法はありません(deferについて読んでいますが、あまり理解できませんでした)。誰か助けてもらえますか?

編集:このような

getContactList機能ルック:

public rx.Observable<Contact> getContactList() { 
    List<Contact> contacts = new ArrayList<>(); 
    ContactCursorWrapper cursorWrapper = queryContacts(null, null); 
    try{ 
     cursorWrapper.moveToFirst(); 
     while (!cursorWrapper.isAfterLast()){ 
      contacts.add(cursorWrapper.getContact()); 
      cursorWrapper.moveToNext(); 
     } 
    } finally { 
     cursorWrapper.close(); 
    } 
    return rx.Observable.from(contacts); 
} 

は、基本的には、データベースを照会し、(POJOである)私の連絡先クラスに返さCursorをマッピングします。 rx.Observable.fromを追加してオブザーバブルを取得し、後でtoListを使用して照合し、アダプタに更新しました。 私はこの方法を使用して、各項目を取得した後にnotifyDataSetChangedに電話する必要がなくなりました。

notifyDataSetChangedコールの数を最小限に抑え、また、onResumeが呼び出されるたびにリフレッシュする正しい方法はありますか?

+0

2回目に 'onError()'を呼び出さないのですか? – JohnWowUs

+0

いいえ、オブザーバーで何も呼び出されません。デバッガは、returnステートメントで 'onContactsReceived'関数に到達するが、' Observer'のメソッドはどれも呼び出されないことを示しています。私は 'observable'を自分で作成していません。' from'関数を直接使って、これと何か関係がありますか? – sudshekhar

+0

Observableを作成していない場合は、 'getContactList()'を呼び出すと毎回新しい観測値が得られない可能性があります。あなたはただ終了していて、連絡先の最初のリストの後に何も放出しない、古い観測を取得しています。あなたの説明から、それは確かに起こっているように聞こえる。 – JohnWowUs

答えて

1

あなたの観察可能なcontactsLab.getContactList().toList()は終了しました。 toList()は、観測可能な観測点からのすべての放射を収集し、監視対象観測点が終了するとリスト全体を放射します(documentation参照)。あなたはそれ以上の排出を観察するつもりはありません。

+0

Ohhそれを指摘してくれてありがとう!私はtoList関数を使用して(図のように) 'adapter'を更新しました。一度にすべての観測データを取得してアダプタを更新するより良い方法を教えてください。 'onNext'にそれらを1つずつ格納し、' onComplete'でアダプタを更新するのが正しい方法でしょうか? – sudshekhar

+0

あなたの 'contactsLab.getContactList()'はどのように見えますか? – JohnWowUs

+0

質問を関連情報で更新しました。基本的に、1回の呼び出しでアダプター上で 'notifyDataSetChanged'を呼び出さずに、カーソルからデータを更新する方法を探しています。 – sudshekhar

関連する問題