2016-09-18 49 views
8

sunucudan arama sonuçlarını getirmek ve RecyclerView içinde (UI iş parçacığı içinde ) onları görüntülemek için. Arama özelliği SearchView, Retrofit ve RxJava (RxBindings) ile nasıl uygulanır? (Arka plan iş parçacığı</strong> içinde <strong>) <code>SearchView</code> Widget içine kullanıcı türleri, uygulama, iç API çağrısı yapmalıdır

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    inflater.inflate(R.menu.my_fragment, menu); 
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); 

    SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); 
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName())); 

    RxSearchView.queryTextChanges(searchView) 
       .debounce(400, TimeUnit.MILLISECONDS) 
       .map(CharSequence::toString) 
       .switchMap(query -> retrofitService.search(query)) 
       .subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe(new Subscriber<List<Item>>() { 
        @Override 
        public void onCompleted() { 

        } 

        @Override 
        public void onError(Throwable e) { 
         Log.e(LOG_TAG, "Error", e); 
        } 

        @Override 
        public void onNext(List<Item> items) { 
         // adapter.addItems(...) 
        } 
       }); 
} 

Ama bir istisna olsun:

benim fragmanında aşağıdaki kodu kullanabilirsiniz ben .subscribeOn(Schedulers.io()) kaldırdığınızda parçası oluşturulduğunda

java.lang.IllegalStateException: Must be called from the main thread. Was: Thread[RxIoScheduler-2,5,main] 
at com.jakewharton.rxbinding.internal.Preconditions.checkUiThread(Preconditions.java:35) 
at com.jakewharton.rxbinding.support.v7.widget.SearchViewQueryTextChangesOnSubscribe.call(SearchViewQueryTextChangesOnSubscribe.java:18) 
at com.jakewharton.rxbinding.support.v7.widget.SearchViewQueryTextChangesOnSubscribe.call(SearchViewQueryTextChangesOnSubscribe.java:10) 
... 

, arama API çağrısı tetiklenir ve hiçbir sorgu SearchView'da yazılmıştır ve ben

retrofit2.adapter.rxjava.HttpException: HTTP 422 

daha sonra, arama sorgumu yazdığımda retrofitService.search(query) artık arandı.

cevap

14

gerçekte rx zincirinde birden observeOn ve birden subscribeOn kullanabilirsiniz unutmayın.

bu deneyin:

RxSearchView.queryTextChanges(searchView) 
      .debounce(400, TimeUnit.MILLISECONDS) 
      .map(CharSequence::toString) 
      .subscribeOn(AndroidSchedulers.mainThread()) 
      .observeOn(Schedulers.io()) 
      .switchMap(query -> retrofitService.search(query)) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Subscriber<List<Item>>() { 
       @Override 
       public void onCompleted() { 

       } 

       @Override 
       public void onError(Throwable e) { 
        Log.e(LOG_TAG, "Error", e); 
       } 

       @Override 
       public void onNext(List<Item> items) { 
        // adapter.addItems(...) 
       } 
      }); 

Bu temelde bu Vida dişi neden olacaktır:

thread usage

+2

Güçlendirme yapılandırırken Aksi takdirde Io iplik belirtebilirsiniz - .addCallAdapterFactory (RxJavaCallAdapterFactory.create (Schedulers .io)) – Outofdate

+0

yep ve sonra '.observeOn (Schedulers.io())' gereksiz olacaktır. –