2015-09-21 11 views
17

का उपयोग करके मैं किसी अन्य थ्रेड (जैसे IO थ्रेड) में okhttp का उपयोग करके यूआरएल से अनुरोध करना चाहता हूं और एंड्रॉइड मुख्य थ्रेड में Response प्राप्त करता हूं, लेकिन मुझे नहीं पता कि Observable कैसे बनाएं।RxJava और Okhttp

उत्तर

19

सबसे पहले अपने निर्भरता को RxAndroid जोड़ें, फिर इस तरह से अपनी Observable बनाएँ:

Subscription subscription = Observable.create(new Observable.OnSubscribe<Response>() { 
     OkHttpClient client = new OkHttpClient(); 
      @Override 
      public void call(Subscriber<? super Response> subscriber) { 
      try { 
       Response response = client.newCall(new Request.Builder().url("your url").build()).execute(); 
       if (response.isSuccessful()) { 
        if(!subscriber.isUnsubscribed()){ 
        subscriber.onNext(response); 
        } 
        subscriber.onCompleted(); 
       } else if (!response.isSuccessful() && !subscriber.isUnsubscribed()) { 
        subscriber.onError(new Exception("error")); 
       } 
      } catch (IOException e) { 
       if (!subscriber.isUnsubscribed()) { 
        subscriber.onError(e); 
       } 
      } 
      } 
     }) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Subscriber<Response>() { 
       @Override 
       public void onCompleted() { 

       } 

       @Override 
       public void onError(Throwable e) { 

       } 

       @Override 
       public void onNext(Response response) { 

       } 
      }); 

यह एक और धागा में अपने यूआरएल (कब धागा) का अनुरोध और एंड्रॉयड मुख्य थ्रेड पर यह निरीक्षण करेंगे।

और अंत में जब आप स्मृति रिसाव से बचने के लिए स्क्रीन subsribtion.unsubscribe() का उपयोग करते हैं।

जब आप Observable.create का उपयोग करते हैं, तो आपको बहुत सारे बॉयलरप्लेट कोड लिखना चाहिए, आपको स्वयं भी सदस्यता को संभालना होगा। defer का उपयोग करने का एक बेहतर विकल्प है। दस्तावेज़ फार्म:

पर्यवेक्षक सदस्याएं तक नमूदार नहीं बनाते हैं, और प्रत्येक पर्यवेक्षक

आस्थगित करें ऑपरेटर प्रतीक्षा करता है जब तक एक पर्यवेक्षक इसे करने के लिए सदस्यता लेता है, और उसके बाद उत्पन्न के लिए एक ताजा प्रत्यक्ष बनाने एक पर्यवेक्षक, आमतौर पर एक पर्यवेक्षण कारखाने समारोह के साथ। यह प्रत्येक ग्राहक के लिए यह नया करता है, इसलिए प्रत्येक ग्राहक को लगता है कि यह एक ही पर्यवेक्षक की सदस्यता ले रहा है, वास्तव में प्रत्येक ग्राहक को अपना व्यक्तिगत अनुक्रम मिलता है।

तो Marcin Koziński के रूप में उल्लेख किया है, तो आप सिर्फ यह करने की आवश्यकता:

final OkHttpClient client = new OkHttpClient(); 
Observable.defer(new Func0<Observable<Response>>() { 
    @Override public Observable<Response> call() { 
     try { 
      Response response = client.newCall(new Request.Builder().url("your url").build()).execute(); 
      return Observable.just(response); 
     } catch (IOException e) { 
      return Observable.error(e); 
     } 
    } 
}); 
+0

सईद द्वारा स्वीकार कर लिया जवाब देने के लिए इसके अलावा, आप चाहते हैं स्मृति रिसाव से बचने के लिए सदस्यता से सदस्यता समाप्त करना चाहते हैं। स्रोत: http://stackoverflow.com/a/34150022/1536976 http://stackoverflow.com/users/3972175/esoxjem – Trilarion

+0

@Trilarion आपका लिंक इस पृष्ठ पर रीडायरेक्ट करने लगता है (पुनरावर्ती!) –

+0

@ विकी सिजवानी आप ' री राइट। यद्यपि यदि आप लिंक को देखते हैं तो मुझे लगता है कि ऐसा कोई अन्य प्रश्न नहीं है जो अब मौजूद नहीं है (इस पृष्ठ के लिंक और मेरा लिंक समान नहीं है)। मुझे नहीं पता कि यहाँ क्या हो रहा है और मुझे याद नहीं है कि यह क्या था। शायद कुछ समय में कहीं कुछ हटा दिया गया है। – Trilarion

16

यह Observable.defer() बजाय Observable.create() उपयोग करने के लिए आसान और सुरक्षित है:

final OkHttpClient client = new OkHttpClient(); 
Observable.defer(new Func0<Observable<Response>>() { 
    @Override public Observable<Response> call() { 
     try { 
      Response response = client.newCall(new Request.Builder().url("your url").build()).execute(); 
      return Observable.just(response); 
     } catch (IOException e) { 
      return Observable.error(e); 
     } 
    } 
}); 

इस तरह से सदस्यता समाप्त करना और backpressure नियंत्रित किया जाता है तुम्हारे लिए। यहां a great post by Dan Lew के बारे में create() और defer() है।

यदि आप Observable.create() मार्ग पर जाना चाहते हैं तो इसे this library में isUnsubscribed() कॉलों के साथ हर जगह छिड़कने की तरह दिखना चाहिए। और मेरा मानना ​​है कि यह अभी भी बैकप्रेसर को संभाल नहीं करता है।

5

मुझे पता है इस पोस्ट के एक सा पुराना है, लेकिन वहाँ ऐसा करने का एक नया और अधिक सुविधाजनक तरीका अब

Observable.fromCallable { 
     client.newCall(Request.Builder().url("your url").build()).execute() 
    } 

अधिक जानकारी है: https://artemzin.com/blog/rxjava-defer-execution-of-function-via-fromcallable/

+0

क्या आप कोड को स्पष्ट कर सकते हैं? 'अनुरोध' से पहले एक 'नया' गायब है, और उसके बाद यह एक त्रुटि –

+2

फेंकता है यह जावा नहीं है, यह कोटलिन – feresr

+0

ओपीएस है ... याद किया गया है, क्षमा करें –