2015-09-24 12 views
9

मैं आरएक्सजेवा सीखना शुरू कर रहा हूं और मुझे अब तक यह पसंद है। मेरे पास एक टुकड़ा है जो बटन क्लिक पर एक गतिविधि के साथ संवाद करता है (वर्तमान खंड को नए टुकड़े के साथ बदलने के लिए)। Google गतिविधि के लिए संवाद करने के लिए टुकड़ों के लिए interface की सिफारिश करता है लेकिन यह भी वर्बोज़ है, मैंने प्रसारण रिसीवर का उपयोग करने की कोशिश की जो आम तौर पर काम करता है लेकिन इसमें कमी आई थी।आरएक्सजेवा घटना बस के रूप में?

चूंकि मैं आरएक्सजेवा सीख रहा हूं, मुझे आश्चर्य है कि क्या यह टुकड़ों से गतिविधियों (या खंड में टुकड़े) से संवाद करने का एक अच्छा विकल्प है? यदि हां, तो इस प्रकार के संचार के लिए आरएक्सजेवा का उपयोग करने का सबसे अच्छा तरीका क्या है? क्या मुझे इस one की तरह इवेंट बस बनाने की ज़रूरत है और यदि ऐसा है तो क्या मुझे बस का एक उदाहरण देना चाहिए और इसे वैश्विक रूप से (विषयों के साथ) उपयोग करना चाहिए?

उत्तर

9

हां और यह सीखने के बाद यह बहुत ही अद्भुत है कि इसे कैसे किया जाए। निम्नलिखित सिंगलटन वर्ग पर विचार करें:

public class UsernameModel { 

    private static UsernameModel instance; 

    private PublishSubject<String> subject = PublishSubject.create(); 

    public static UsernameModel instanceOf() { 
     if (instance == null) { 
      instance = new UsernameModel(); 
     } 
     return instance; 
    } 

    /** 
    * Pass a String down to event listeners. 
    */ 
    public void setString(String string) { 
     subject.onNext(string); 
    } 

    /** 
    * Subscribe to this Observable. On event, do something e.g. replace a fragment 
    */ 
    public Observable<String> getStringObservable() { 
     return subject; 
    } 

} 

अपनी गतिविधि में घटनाओं प्राप्त करने के लिए तैयार हो (जैसे onCreate में यह राशि):

UsernameModel usernameModel = UsernameModel.instanceOf(); 

//be sure to unsubscribe somewhere when activity is "dying" e.g. onDestroy 
subscription = usernameModel.getStringObservable() 
     .subscribe(s -> { 
      // Do on new string event e.g. replace fragment here 
     }, throwable -> { 
      // Normally no error will happen here based on this example. 
     }); 

आप में टुकड़ा नीचे घटना से पारित जब यह होता है:

UsernameModel.instanceOf().setString("Nick"); 

आपकी गतिविधि तब कुछ करेगी।

युक्ति 1: किसी ऑब्जेक्ट प्रकार के साथ स्ट्रिंग को बदलें।

टिप 2: यदि आपके पास निर्भरता इंजेक्शन है तो यह भी बहुत अच्छा काम करता है।


अद्यतन: मैं एक और अधिक लंबा article

+1

1. आपका उदाहरण इस "चिपचिपा" को देखने के लिए 'व्यवहार विषय' के साथ बेहतर होगा। यानी नई सदस्यता अंतिम मूल्य देखेंगे। आप शायद चाहते हैं कि वैल्यू पर निर्भर नए दृश्य सदस्यता पर सही ढंग से अपडेट हो जाएंगे। 2. 'उपयोगकर्ता नाम मॉडल' वास्तव में केवल एक चीज करता है: 'PublishSubject' को लपेटता है और इसे सिंगलटन बनाता है। डी सिंगलेट्स प्रदान करता है! यदि आप DI का उपयोग कर रहे थे तो आप सीधे 'PublishSubject' या' BehaiorSubject' को इंजेक्ट करेंगे। यदि आप डैगर का उपयोग कर रहे हैं, तो आप 'विषय' इंजेक्ट करने के लिए '@ नामांकित (" उपयोगकर्ता नाम ")' का उपयोग कर सकते हैं। – Andy

+0

इसी तरह के कार्यान्वयन [नीचे जवाब देखें] (https://stackoverflow.com/a/48300275/4647628) – Aks4125

2

वर्तमान में मुझे लगता है कि इस सवाल का मेरे पसंदीदा दृष्टिकोण को यह है लिखा है:

1.) के बजाय एक वैश्विक बस कि पूरे ऐप में सब कुछ संभालता है (और इसके परिणामस्वरूप काफी अनावश्यक हो जाता है) स्पष्ट रूप से परिभाषित उद्देश्यों के लिए "स्थानीय" बसों का उपयोग करें और केवल उन्हें उस स्थान पर प्लग करें जहां आपको उनकी आवश्यकता है।

उदाहरण के लिए आप हो सकता है: अपने Activity रों और अपने ApiService के बीच डेटा भेजने के लिए

  • एक बस।
  • Activity में कई Fragment एस के बीच संचार के लिए एक बस।
  • एक बस जो वर्तमान में चयनित ऐप थीम रंग को सभी Activity एस भेजती है ताकि वे तदनुसार सभी आइकन टेंट कर सकें।

2.) का प्रयोग करें डैगर (या शायद AndroidAnnotations अगर आपको लगता है कि) तारों-सब कुछ-एक साथ एक सा कम दर्दनाक बनाने के लिए (और यह भी static उदाहरणों के बहुत से बचने के लिए पसंद करते हैं)। यह भी आसान बनाता है, ई। जी। एक ऐसा घटक है जो SharedPreferences में लॉगिन स्थिति को संग्रहीत करने और पढ़ने के साथ ही संबंधित है - इस घटक को सभी अनुरोधों के लिए सत्र टोकन प्रदान करने के लिए सीधे आपके ApiService पर भी तारित किया जा सकता है।

3।) return subject.asObservable() पर कॉल करके उन्हें जनता को सौंपने से पहले उन्हें Subject आंतरिक रूप से उपयोग करने के लिए स्वतंत्र महसूस करें, लेकिन Observable पर उन्हें "कास्ट" करें। यह अन्य वर्गों को मूल्यों को Subject में धक्का देने से रोकता है जहां उन्हें अनुमति नहीं दी जानी चाहिए।

+1

वास्तव में मुझे आश्चर्य है, घटना बस के कई उदाहरण होने का क्या मतलब है? यह उच्च एकजुटता में योगदान नहीं करता है। एक उदाहरण के बजाय, आप बिना किसी वास्तविक लाभ के एक ही चीज़ के कई उदाहरण समाप्त कर देंगे। – Gunhan

+0

@ गुहान चारों ओर कम कास्टिंग। एक विशिष्ट बस में एक विशिष्ट संचार मॉडल होता है। यदि आपको "SomeObject" परिवर्तनों को सुनने की आवश्यकता है, तो उसी बस के माध्यम से SomeObjects क्यों भेजें जहां "SomeOtherObject" यात्रा कर रहा हो। कंक्रीट बसें विशिष्ट जानकारी के बहु-परत लेन समर्पित हैं। –

0

परिभाषित घटनाओं

public class Trigger { 

public Trigger() { 
} 

public static class Increment { 
} 

public static class Decrement { 
} 

public static class Reset { 
} 
} 

घटना नियंत्रक

public class RxTrigger { 

private PublishSubject<Object> mRxTrigger = PublishSubject.create(); 

public RxTrigger() { 
    // required 
} 

public void send(Object o) { 
    mRxTrigger.onNext(o); 
} 

public Observable<Object> toObservable() { 
    return mRxTrigger; 
} 
// check for available events 
public boolean hasObservers() { 
    return mRxTrigger.hasObservers(); 
} 
} 

Application.class

public class App extends Application { 

private RxTrigger rxTrigger; 

public App getApp() { 
    return (App) getApplicationContext(); 
} 

@Override 
public void onCreate() { 
    super.onCreate(); 
    rxTrigger = new RxTrigger(); 
} 


public RxTrigger reactiveTrigger() { 
    return rxTrigger; 
} 


} 

रजिस्टर घटना श्रोता जहाँ भी आवश्यक

   MyApplication mApp = (App) getApplicationContext(); 
       mApp 
        .reactiveTrigger() // singleton object of trigger 
        .toObservable() 
        .subscribeOn(Schedulers.io()) // push to io thread 
        .observeOn(AndroidSchedulers.mainThread()) // listen calls on main thread 
        .subscribe(object -> { //receive events here 
         if (object instanceof Trigger.Increment) { 
          fabCounter.setText(String.valueOf(Integer.parseInt(fabCounter.getText().toString()) + 1)); 
         } else if (object instanceof Trigger.Decrement) { 
          if (Integer.parseInt(fabCounter.getText().toString()) != 0) 
           fabCounter.setText(String.valueOf(Integer.parseInt(fabCounter.getText().toString()) - 1)); 
         } else if (object instanceof Trigger.Reset) { 
          fabCounter.setText("0"); 
         } 
        }); 

संदेश/आग घटना

MyApplication mApp = (App) getApplicationContext(); 
//increment 
mApp 
    .reactiveTrigger() 
    .send(new Trigger.Increment()); 

//decrement 
mApp 
    .reactiveTrigger() 
    .send(new Trigger.Decrement()); 
उदाहरण से पुस्तकालय के लिए

पूर्ण कार्यान्वयन ->RxTrigger

0,123,
संबंधित मुद्दे