2014-07-16 17 views
9

मैं अपने एसिंक नेटवर्क कॉल के लिए rxjava ऑब्जर्जेबल को वापस करने के लिए रेट्रोफिट का उपयोग कर रहा हूं।Android पर rxjava के लिए डिफ़ॉल्ट शेड्यूलर

मैं अपने आप को निम्नलिखित मंगलाचरण दोहरा पाते हैं:

someApiCall().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())

लगता है जैसे मैं हमेशा आईओ धागे पर सदस्यता लेने रहा हूँ और एंड्रॉयड मुख्य थ्रेड पर अवलोकन। यह सबसे अच्छा प्रथा प्रतीत होता है कि मुझे सभी संसाधनों को वकील मिला। शायद लंबे समय से चलने वाले कंप्यूटेशंस के अलावा, मैं समझ नहीं पा रहा हूं कि जब हम इस पैटर्न से विचलित होना चाहते हैं।

क्या सदस्यता लेने के लिए इस बॉयलरप्लेट को हटाने का कोई तरीका है सदस्यता लें और धागे पर निरीक्षण करें?

क्या यह rxjava plugins के लिए उपयोग का मामला है? (मुझे उनके उपयोग के कई उदाहरण नहीं मिल रहे हैं।)

क्या मैं retrofit executors के साथ गड़बड़ कर नेटवर्क सीमा पर डिफ़ॉल्ट धागे सेट कर सकता हूं?

+0

इसे थोड़ा सा ड्रॉ करने के लिए यहां मेरा प्रश्न/उत्तर देखें: http://stackoverflow.com/a/25576177 – ktusznio

उत्तर

10

Observable प्रतिक्रियाओं के लिए, रेट्रोफिट वर्तमान में subscribeOn को RestAdapter (या तो प्रदान किया गया या डिफ़ॉल्ट) के HTTP निष्पादक के रूप में सेट करता है। यह मौजूदा व्यवहार में आरएक्सजेवा समर्थन को छेड़छाड़ करने के लिए किया गया था।

2.0 के लिए योजना subscribeOn और observeOn दोनों के लिए डिफ़ॉल्ट सेट करने की क्षमता प्रदान करना है (चाहे वह दोनों, केवल एक या न हो)।

एक कारण है कि आप हमेशा मुख्य धागे पर अवलोकन नहीं करना चाहते हैं, उदाहरण के लिए, यदि आपको एक से अधिक एपीआई कॉल एक साथ श्रृंखला की आवश्यकता होती है।

+0

संस्करण 1 में।9, मैंने पाया कि वाद्ययंत्र परीक्षण डेडलॉक्स के दौरान 'subscribeOn (कुछ)' (आमतौर पर 'Schedulers.io()') को कॉल नहीं किया जाता है। क्या यह एक अपेक्षित व्यवहार है? – njzk2

4

रेट्रोफिट संस्करण 2.0.0-बीटा 2 (2015-09-28) के Change Log दिखाता है सदस्यता लें() पृष्ठभूमि में चलाने के लिए आवश्यक है।

फिक्स्ड: अनुरोधों का अवलोकन और एकल-आधारित निष्पादन अब समकालिक रूप से व्यवहार करता है (और इस प्रकार पृष्ठभूमि में चलाने के लिए subscribeOn() की आवश्यकता होती है)।

2

हाँ, दोनों कॉल को निकालना संभव है।

public class RxThreadingCallAdapterFactory extends CallAdapter.Factory { 
    private final RxJava2CallAdapterFactory original; 

    private RxThreadingCallAdapterFactory() { 
     // Always call on background thread 
     original = RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()); 
    } 

    public static CallAdapter.Factory create() { 
     return new RxThreadingCallAdapterFactory(); 
    } 

    @Override 
    public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { 
     return new RxCallAdapterWrapper(original.get(returnType, annotations, retrofit)); 
    } 

    private static class RxCallAdapterWrapper implements CallAdapter<Observable<?>> { 
     private final CallAdapter<?> wrapped; 

     public RxCallAdapterWrapper(CallAdapter<?> wrapped) { 
      this.wrapped = wrapped; 
     } 

     @Override 
     public Type responseType() { 
      return wrapped.responseType(); 
     } 

     @Override 
     public <R> Observable<?> adapt(Call<R> call) { 
      Observable observable = (Observable) wrapped.adapt(call); 

      // Always handle result on main thread 
      return observable.observeOn(AndroidSchedulers.mainThread()); 
     } 
    } 
} 

जब पुराना वापस को विन्यस्त फिर इस एडाप्टर का उपयोग:

Retrofit.Builder() 
    .baseUrl(...) 
    .addCallAdapterFactory(RxThreadingCallAdapterFactory.create()) 

यहाँ पुराना वापस एडाप्टर वर्ग कि स्वचालित रूप से कार्यक्रम subscribeOn और observedOn दोनों एक मंगलाचरण में बॉयलरप्लेट कॉल की आवश्यकता को दूर करने के लिए है

मैंने this blog post लिखा जो वास्तव में यहां क्या हो रहा है पर बहुत अधिक जानकारी देता है।

यह दोनों कॉल को हटा देगा, जिसे मैं बॉयलरप्लेट पर विचार करता हूं। मैं जैक के पृष्ठभूमि कॉल को एक साथ जोड़ने की परिदृश्य पर विचार करता हूं जो वास्तव में लागू नहीं होता है, क्योंकि इस मामले में मैं सिंक्रोनस कॉल को दोबारा कर दूंगा और शेड्यूलर का उपयोग नहीं करूँगा।

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