2017-04-07 10 views
8

मैं दृश्य क्लिक RxJava 2. का उपयोग कर श्रोता मैं सबसे सरल कार्यान्वयन से शुरू से एक Observable बनाना चाहते हैं (मैं यहाँ lambdas का उपयोग नहीं करते आप इस विधि में विभिन्न प्रकार को दिखाने के लिए):RxJava 2 रद्द करने योग्य और डिस्पोजेबल के बीच क्या अंतर है?

Observable<View> viewObservable = Observable.create(new ObservableOnSubscribe<View>() { 
     @Override 
     public void subscribe(@NonNull ObservableEmitter<View> e) throws Exception { 
      mNewWordView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View value) { 
        if (!e.isDisposed()) { 
         e.onNext(value); 
        } 
       } 
      }); 
     } 
    }); 

तो मैंने सोचा था कि onClickListener को शून्य के लिए सेट करने के तरीके के बारे में यदि इसकी आवश्यकता नहीं है। मैंने पाया वहाँ नाम (मेरे लिए) के रूप में इसी तरह के साथ दो तरीके हैं कि:

e.setCancellable(Cancellable c); और e.setDisposable(Disposable d);

उन्हें और जो मैं इस्तेमाल करना चाहिए के बीच क्या अंतर है?

उत्तर

14

Javadoc से:

एक विधि एकल रद्द कि फेंक सकता है कि एक कार्यात्मक इंटरफ़ेस [Cancellable है]।

Disposable एक कार्यात्मक इंटरफ़ेस नहीं है प्लस जब इसकी dispose() विधि को लागू करने के लिए, आप जांचे हुए अपवादों फेंकने के लिए अनुमति नहीं है।

इसके विपरीत, कई गैर RxJava घटकों वापसी एक Closeable या AutoCloseable जो throws IOException और throws Exception के माध्यम से परिभाषित और एक बोझ कुछ हद तक कर रहे हैं रहे हैं क्योंकि आप की कोशिश-पकड़ की जरूरत होगी।

उदाहरण के लिए, आप setCancellable उपयोग करने के लिए जब आप एक फ़ाइल के साथ कार्य करना चाहेंगे:

Observable.create((ObservableEmitter<byte[]> e) -> { 
    FileInputStream fin = new FileInputStream("raw.dat"); 
    e.setCancellable(fin::close); 

    byte[] buffer = new byte[4096]; 

    for (;;) { 
     int r = fin.read(buffer); 
     if (r < 0) { 
      break; 
     } 
     e.onNext(buffer); 
    } 
    e.onComplete(); 
}); 

और आप setDisposable का उपयोग करते हैं तो आप एक Scheduler का उपयोग करें:

Observable.create((ObservableEmitter<Event> e) -> { 
    Worker worker = Schedulers.io().createWorker(); 
    e.setDisposable(worker); 

    eventSource.onEvent(es -> 
     worker.schedule(() -> e.onNext(es)) 
    ); 
}); 
+0

धन्यवाद। अगर मैं रद्द करने योग्य और विस्थापित नहीं करता हूं तो क्या मुझे चेक करें (! E.isDisposed()) 'का उपयोग करना चाहिए? – Gaket

+0

हां, डाउनस्ट्रीम निपटान कॉल isDisposed() के माध्यम से ठीक से परिलक्षित होता है इससे कोई फर्क नहीं पड़ता कि आपके पास कौन से संसाधन हैं। – akarnokd

+1

इस मूल मामले के लिए, आपको वास्तव में इसकी आवश्यकता नहीं है, लेकिन यदि आप 'ऑनरर' उत्सर्जित करना चाहते हैं, तो इसे एक डिस्प्लेड() चेक की सलाह दी जाती है क्योंकि अगर उत्सर्जक का निपटारा किया जाता है, तो त्रुटि वैश्विक त्रुटि पर जा दी जाएगी हैंडलर जो एंड्रॉइड ऐप को अकसर अप्रत्याशित रूप से क्रैश करता है। – akarnokd

6

CancellableDisposable में लपेटकर समाप्त होता है ताकि अंतिम प्रभाव किसी भी कॉल के लिए समान हो। अंतर यह है कि Disposable में ऐसी कई सुविधाएं हैं जिन्हें आप कार्यान्वित नहीं करना चाहते हैं, इसलिए सरल Cancellable इंटरफ़ेस एक विकल्प के रूप में है।

यदि आप अवलोकन योग्य समाप्त होते हैं तो Cancellable का उपयोग करते समय आप कुछ निपटाना चाहते हैं। यदि आपके पास कोई संसाधन है जिसे Disposable.isDisposed() विधि को लागू करने के लिए Disposable को लागू करने के लिए कुछ बाहरी कारणों से निपटान किया जा सकता है।

ध्यान दें कि विधियां पारस्परिक रूप से अनन्य हैं। केवल एक ही डिस्पोजेबल या रद्द करने योग्य एक बार में पंजीकृत किया जा सकता है। कॉलिंग पहले दोनों को ओवरराइट करता है।

+0

धन्यवाद। क्या मैं चेक 'if (! E.isDisposed()) 'का उपयोग कर सकता हूं, यदि मैं रद्द करने योग्य नहीं हूं और विस्थापित नहीं हूं? – Gaket

+0

अकर्णोकड आरएक्सजेवा डेवलपर्स में से एक है और उसका उदाहरण इसका उपयोग नहीं करता है ताकि जांच की जा सके कि शायद इसकी आवश्यकता नहीं है। जहां तक ​​मुझे पता है कि इस तरह की चेक केवल 'ऑनरर कॉल' पर आवश्यक है क्योंकि एक डिस्पोजेड अवलोकन योग्य पर एक त्रुटि वैश्विक अपवाद हैंडलर पर जाएगी। – Kiskae

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