2016-03-02 34 views
21

मेरे पास एक अवलोकन करने योग्य सदस्यता के बारे में कोई प्रश्न है। मेरे पास दो कोड हैं और मुझे सच में यकीन नहीं है कि कौन सा बेहतर है।सदस्यता सदस्यता रद्द करने के लिए

उदाहरण 1 - ग्राहक एक बार धारा समाप्त हो गया है सदस्यता रद्द करें>:

Subscriber<String> subscriber = new Subscriber<String>() { 
     @Override 
     public void onCompleted() { 
      progressdialog.dissmiss(); 
      unsubscribe(); 
     } 

     @Override 
     public void onError(Throwable e) { 
      progressdialog.dissmiss(); 
     } 

     @Override 
     public void onNext(String s) { 
      // do something with data 
     } 
    } 

उदाहरण 2 -> सदस्यता एक बार गतिविधि नष्ट हो जाता है सदस्यता रद्द करें:

private void test(){ 
    Subscriber<String> subscriber = new Subscriber<String>() { 
     @Override 
     public void onCompleted() { 
      progressdialog.dissmiss(); 
     } 

     @Override 
     public void onError(Throwable e) { 
      progressdialog.dissmiss(); 
     } 

     @Override 
     public void onNext(String s) { 
      // do something with data 
     } 
    }; 

    subscription = BackendRequest.login(loginRequest) 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(subscriber); 

    compositeSubscription.add(subscription); 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    this.subscription.unsubscribe(); 
} 

मुझे लगता है कि उल्लेख करना होगा मेरी अवलोकन केवल एक बार उत्सर्जित हो जाएंगे, गतिविधि को पर्यवेक्षण से अधिक कॉल के लिए इंतजार नहीं करना चाहिए।

कौन सा बेहतर है?

अग्रिम धन्यवाद

+0

श्रोता को रीफ्रेश करने के लिए पुल का उपयोग करते समय दूसरी बार रीफ्रेश करने के लिए मुझे अपना कोड (रीफ्रेश करने के लिए खींचें) प्राप्त करने में परेशानी हो रही है। मैंने सत्यापित किया है कि रीफ्रेश करने के लिए मेरी खींच सही ढंग से काम कर रही है लेकिन "observable.subscribeOn (शेड्यूलर्स.न्यू थ्रेड()) का दूसरा सेट। निरीक्षण (एंड्रॉइडशेड्यूलर्स.माइन थ्रेड())। सदस्यता लें (ग्राहक)" केवल काम नहीं कर रहा है। कोई विचार? – lawonga

उत्तर

21

दो विकल्पों में से दूसरा दूसरा बेहतर है।

आपके पहले उदाहरण में आप unsubscribingonComplete() विधि में आवश्यक नहीं हैं। यदि आप सदस्यता के onComplete() तक पहुंचते हैं तो आपके पास अब से सदस्यता रद्द करने की ज़िम्मेदारी नहीं है।

आपका दूसरा उदाहरण सही है। CompositeSubscription के पीछे विचार यह है कि आप इसे कई Subscriptions जोड़ सकते हैं और फिर एक बार में (unsubscribe) साफ़ कर सकते हैं। दूसरे शब्दों में यह आपको Subscriptions की सूची रखने की आवश्यकता से बचाता है जिसे आपको सदस्यता समाप्त करने की आवश्यकता है। CompositeSubscription का उपयोग कर

एक मुश्किल बात यह है कि अगर आप एक बार unsubscribe यह, आप नहीं इसे फिर से उपयोग कर सकते हैं। विवरण के लिए आप compositeSubscription.add() विधि के लिए प्रलेखन की जांच कर सकते हैं। संक्षेप में - यह उस सदस्यता को सीधे सदस्यता लेगा जिसे आप जोड़ना चाहते हैं। यह एक जानबूझकर निर्णय रहा है (आप इसे HERE के बारे में अधिक पढ़ सकते हैं)।

गतिविधि के onDestroy() में unsubscribe() पर कॉल करना ठीक है और आपको स्मृति रिसाव से बचाएगा। आपकी टिप्पणी के संबंध में समस्याएं तब होती हैं जब आप अपनी test() विधि को कई बार कॉल करते हैं - मैं कहूंगा कि आपकी समस्या कहीं और है। हो सकता है कि आपके उपयोग-मामले को इसे कई बार कॉल करने की अनुमति न दे, शायद आपको नए प्राप्त किए गए एक का उपयोग करने से पहले पुराने डेटा को साफ करना चाहिए। शायद यदि आपने विवरण में समझाया है कि आपको किस प्रकार की समस्याएं आती हैं तो हम और अधिक मदद कर सकते हैं। लेकिन जहां तक ​​CompositeSubscription संबंधित है - आप इसका उपयोग कर रहे हैं और इसे सही तरीके से सदस्यता रद्द कर रहे हैं!

+7

लेकिन 'ऑनडेस्ट्राय' को कॉल करने की गारंटी नहीं है। क्या इसका मतलब यह है कि अगर किसी कारण के लिए 'ऑनडेस्ट्राय' को बुलाया नहीं जाता है तो स्मृति रिसाव होगी क्योंकि इस मामले में 'सदस्यता रद्द' नहीं कहा जाता है? – Storix

+0

चूंकि आपका 'पर्यवेक्षण योग्य' केवल एक आइटम उत्सर्जित करता है, इसके बजाय 'सिंगल' का उपयोग क्यों न करें? 'OnNext()' के बजाय, यह एक बार 'सिंगल सदस्यताकर्ता' की 'ऑन-असफल() 'को कॉल करता है, और फिर यह किया जाता है (कोई' पूर्ण()' कॉल नहीं है)। –

3

मुझे लगता है कि आपकी आवश्यकताओं पर निर्भर करता है। यदि गतिविधि किसी अन्य कॉल के लिए इंतजार नहीं करेगी, तो मुझे लगता है कि आप पूर्ण() पर अंदर सदस्यता रद्द कर सकते हैं।

मैं हमेशा OnDestroy में सदस्यता समाप्त()

@Override 
protected void onDestroy() { 
    super.onDestroy(); 

    if (subscription != null) { 
     subscription.unsubscribe(); 
    } 
} 

संपादित करें: http://reactivex.io/RxJava/javadoc/rx/subscriptions/CompositeSubscription.html

private CompositeSubscription mCompositeSubscription = new CompositeSubscription(); 

private void doSomething() { 
    mCompositeSubscription.add(
     AndroidObservable.bindActivity(this, Observable.just("Hello, World!")) 
     .subscribe(s -> System.out.println(s))); 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    mCompositeSubscription.unsubscribe(); 
} 
+0

उदाहरण 2 के साथ आपको कई सब्सक्रिप्शन (सदस्य चर) घोषित करना होगा जैसे आप गतिविधि में उपयोग करते हैं और नष्ट करने पर उन्हें सबकुछ सदस्यता छोड़ते हैं, है ना? – MarcForn

+0

@MarcForn मेरे संपादन की जांच करें –

+0

मेरी प्रोजेक्ट में मैं कंपोजिट सदस्यता का उपयोग कर रहा हूं, और परीक्षण विधि के अंदर मैं कंपोजिट सदस्यता के लिए सदस्यता जोड़ता हूं। मुझे मिली समस्या (और पोस्ट का कारण यही है) परीक्षण विधि को कई बार कॉल करने के बारे में है। ऐसा करने से मुझे एहसास हुआ कि हमारे पास एन सदस्यता (वही) कंपोजिट सदस्यता सूची में जोड़ा गया है। – MarcForn

24

पर एक नज़र डालें onCompleted में सदस्यता समाप्त करने की कोई जरूरत नहीं है। एक नमूदार मुद्दों एक OnError या उसके पर्यवेक्षकों के OnComplete अधिसूचना, इस सदस्यता को समाप्त करता है The Observable Contract

पर एक नजर डालें। द्वारा समाप्त किए गए सब्सक्रिप्शन को समाप्त करने के लिए पर्यवेक्षकों को जारी करने की आवश्यकता नहीं है, जो इस तरह से अवलोकन योग्य हैं।

दूसरी ओर, आपको स्मृति रिसाव को रोकने के लिए निश्चित रूप से onDestroy में सदस्यता समाप्त करनी चाहिए।

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