2015-07-30 10 views
14

मैं एंड्रॉइड पर्यावरण के अंदर rxjava सीखने की कोशिश कर रहा हूं। मान लें कि मेरे पास एक अवलोकन योग्य है जो नेटवर्क कॉल के परिणाम को छोड़ देता है।RxJava Observable.cache अमान्य

  • दुकान एक बनाए रखा टुकड़ा/सिंगलटन/आवेदन वस्तु

  • में नमूदार को कैश ऑपरेटर लागू: अगर मैं सही ढंग से समझ, एक व्यापक रूप से आम दृष्टिकोण config परिवर्तन से निपटने के लिए करने के लिए है नमूदार

  • की सदस्यता लेने/उचित जीवन चक्र संचालकों में सदस्यता समाप्त

ऐसा करने से, हम अवलोकन के परिणाम को नहीं खोलेंगे जो नई कॉन्फ़िगरेशन होने के बाद फिर से पर्यवेक्षित होगा।

अब, मेरे सवाल यह है:

वहाँ एक नया मान फेंकना (और कैश की गई एक अमान्य) करने के लिए मजबूर करने के लिए नमूदार कोई तरीका है? क्या मुझे हर बार एक नया अवलोकन करने की ज़रूरत है जब मैं नेटवर्क से ताजा डेटा चाहता हूं (जो एंड्रॉइड दुनिया में खराब अभ्यास की तरह नहीं लगता है क्योंकि जीसी अतिरिक्त काम करता है)?

धन्यवाद एक बहुत,

फेडरिको

उत्तर

18

करता है कि आप क्या चाहते हैं एक कस्टम OnSubscribe कार्यान्वयन करें:

public static class OnSubscribeRefreshingCache<T> implements OnSubscribe<T> { 

    private final AtomicBoolean refresh = new AtomicBoolean(true); 
    private final Observable<T> source; 
    private volatile Observable<T> current; 

    public OnSubscribeRefreshingCache(Observable<T> source) { 
     this.source = source; 
     this.current = source; 
    } 

    public void reset() { 
     refresh.set(true); 
    } 

    @Override 
    public void call(Subscriber<? super T> subscriber) { 
     if (refresh.compareAndSet(true, false)) { 
      current = source.cache(); 
     } 
     current.unsafeSubscribe(subscriber); 
    } 

} 

कोड के इस बिट के उपयोग को दर्शाता है और पता चलता है कि कैश रीसेट अनिवार्य रूप से किया जा रहा है:

Observable<Integer> o = Observable.just(1) 
     .doOnCompleted(() -> System.out.println("completed")); 
OnSubscribeRefreshingCache<Integer> cacher = 
    new OnSubscribeRefreshingCache<Integer>(o); 
Observable<Integer> o2 = Observable.create(cacher); 
o2.subscribe(System.out::println); 
o2.subscribe(System.out::println); 
cacher.reset(); 
o2.subscribe(System.out::println); 

आउटपुट:

completed 
1 
1 
completed 
1 

वैसे आप देख सकते हैं कि .cache पूरा होने तक उत्सर्जन नहीं करेगा। यह एक बग है जिसे आरएक्सजेवा 1.0.14 द्वारा तय किया जाना चाहिए।

आपके जीसी दबाव चिंताओं के संदर्भ में, जब एक पर्यवेक्षक पर लागू होता है तो प्रत्येक ऑपरेटर आमतौर पर lift या create के माध्यम से एक नया पर्यवेक्षण बनाता है। एक नया अवलोकन करने के साथ जुड़े मूल सदस्य राज्य onSubscribe फ़ंक्शन का संदर्भ है। cache सबसे अधिक से अलग है जिसमें यह सब्सक्रिप्शन में राज्य रखता है और इसमें जीसी दबाव के लिए संभावित क्षमता होती है यदि इसमें बहुत सारी स्थिति होती है और उसे अक्सर फेंक दिया जाता है। यहां तक ​​कि यदि आपने रीसेट में राज्य को पकड़ने के लिए एक ही म्यूटेबल डेटा स्ट्रक्चर का उपयोग किया है, तो भी जीसी को डेटा संरचना की सामग्री को तब तक निपटाना होगा जब आपको मंजूरी मिलती है ताकि आपको ज्यादा लाभ न हो।

आरएक्सजेवा cache ऑपरेटर एकाधिक समवर्ती सदस्यता के लिए बनाया गया है। आप शायद कल्पना कर सकते हैं कि एक रीसेट कार्यक्षमता लागू करने के लिए समस्याग्रस्त साबित हो सकती है। यदि आप आगे का पता लगाना चाहते हैं तो हर तरह से आरएक्सजेवा जीथ्यूब पर एक मुद्दा उठाएं।

+0

थोड़ा साफ –

+0

साफ दिखता है! हालांकि, ऐसा करने से हमारे पास एक और अधिक सुरुचिपूर्ण और आरएक्स-ईश एपीआई है लेकिन मुझे लगता है कि हम सिर्फ देखने योग्य मनोरंजन को छुपा रहे हैं। अगर मैंने rxjava के स्रोत को गलत नहीं पढ़ा है, तो कैश() एक नया (कैश किया गया) देखता है: https: // github।com/ReactiveX/RxJava/blob/230bdca4b674f7d8c6ce13b47d33fe9598ad89bb/src/main/java/rx/internal/operators/cachedObservable.java # L56 – fedepaol

+1

पर्यवेक्षण निर्माण के बारे में नोट्स के साथ अद्यतन किया गया। –