2016-09-18 16 views
8

SearchView विजेट में उपयोगकर्ता प्रकार, अनुप्रयोग एक API कॉल करना चाहिए जब (पृष्ठभूमि धागा में) सर्वर से खोज परिणाम लाने, और उन्हें RecyclerView में (यूआई धागा में) प्रदर्शित करने के लिए।सर्च व्यू, रेट्रोफिट और आरएक्सजेवा (आरएक्सबिंडिंग्स) के साथ खोज सुविधा को कैसे कार्यान्वित करें?

मैं अपने टुकड़ा में निम्न कोड का उपयोग करें:

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

लेकिन मैं एक अपवाद प्राप्त करें:

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) 
... 

जब मैं .subscribeOn(Schedulers.io()) निकालने के लिए, खोज API कॉल जब टुकड़ा बनाई गई है निकाल दिया जाता है और SearchView में कोई प्रश्न टाइप नहीं किया गया है और मुझे एक्सपशन

retrofit2.adapter.rxjava.HttpException: HTTP 422 

तब, जब मैं अपनी खोज क्वेरी टाइप करता हूं retrofitService.search(query) अब कॉल नहीं किया जाता है।

उत्तर

14

याद रखें कि आप वास्तव में अपने आरएक्स श्रृंखला में एकाधिक observeOn और एकाधिक subscribeOn ऑपरेटरों का उपयोग कर सकते हैं।

इस प्रयास करें:

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

यह मूलतः इस थ्रेड उपयोग में परिणाम होगा:

thread usage

+2

नहीं तो आप जब रेट्रोफिट को विन्यस्त आईओ धागा निर्दिष्ट कर सकते हैं - .addCallAdapterFactory (RxJavaCallAdapterFactory.create (Schedulers .io)) – Outofdate

+0

हाँ, और फिर '.observeOn (Schedulers.io()) 'अनावश्यक होगा –

संबंधित मुद्दे