2012-04-26 14 views
11

क्या एंड्रॉइड में आईओएस क्लास NSNotificationCenter के बराबर है? क्या मेरे पास कोई पुस्तकालय या उपयोगी कोड उपलब्ध है?एंड्रॉइड में आईओएस NSNotificationCenter के समतुल्य?

+0

क्या आपका मतलब NSNotificationCenter, या अधिसूचना छाया है? – CodaFi

+0

NSNotificationCenter हालांकि मुझे नहीं पता कि अधिसूचना छाया क्या है :) मेरी आवश्यकता है पर्यवेक्षक पैटर्न के माध्यम से कई पर्यवेक्षकों को ईवेंट प्रसारित करना। – user310291

+1

ऐसा लगता है कि [LocalBroadcastRecievers API] (http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html) वह है जिसे आप ढूंढ रहे हैं। – CodaFi

उत्तर

17

एंड्रॉइड में आईओएस में केंद्रीय अधिसूचना केंद्र नहीं है। लेकिन आप अपने कार्य को प्राप्त करने के लिए मूल रूप से Observable और Observer ऑब्जेक्ट्स का उपयोग कर सकते हैं।

तुम कुछ की तरह एक वर्ग को परिभाषित कर सकते हैं नीचे, बस इसे सिंगलटन उपयोग के लिए संशोधित करने और समवर्ती उपयोग के लिए सिंक्रनाइज़ जोड़ लेकिन यह विचार एक ही है:

public class ObservingService { 
    HashMap<String, Observable> observables; 

    public ObservingService() { 
     observables = new HashMap<String, Observable>(); 
    } 

    public void addObserver(String notification, Observer observer) { 
     Observable observable = observables.get(notification); 
     if (observable==null) { 
      observable = new Observable(); 
      observables.put(notification, observable); 
     } 
     observable.addObserver(observer); 
    } 

    public void removeObserver(String notification, Observer observer) { 
     Observable observable = observables.get(notification); 
     if (observable!=null) {   
      observable.deleteObserver(observer); 
     } 
    }  

    public void postNotification(String notification, Object object) { 
     Observable observable = observables.get(notification); 
     if (observable!=null) { 
      observable.setChanged(); 
      observable.notifyObservers(object); 
     } 
    } 
} 
+0

कोड नमूना के लिए ठीक है धन्यवाद :) – user310291

+0

आपको "notifyObservers()" को कॉल करने से पहले (या कम से कम मेरे मामले में) "setChanged()" विधि को कॉल करें। तो मैंने अपना कस्टम अवलोकन योग्य बनाया: http://pastebin.com/hqCuKRzW – jihonrado

+0

मैंने अपना मूल उत्तर @ जिहोनराडो संपादित किया, धन्यवाद –

8

स्क्वायर से ओटो घटना बस पर एक नज़र डालें:

http://square.github.com/otto/

यह मूलतः एक ही आसान है घटकों और रास्तों कि घटनाओं का पालन करें की निर्भरता का पालन करने के एनोटेशन और स्थिर टाइपिंग के लिए NSNotificationCenter के रूप में सुविधाओं, लेकिन धन्यवाद है। स्टॉक एंड्रॉइड प्रसारण एपीआई, आईएमओ की तुलना में उपयोग करना बहुत आसान है।

2

आप ऑब्जर्वर उपयोग करने के लिए नहीं करना चाहते हैं - यह मामलों आप एक टुकड़ा अपने पर्यवेक्षक कारण आप एक से अधिक वर्ग विस्तार नहीं कर सकते कि आप Google की अमरूद लाइब्रेरी (https://code.google.com/p/guava-libraries/) उपयोग कर सकते हैं होना चाहता हूँ में समस्या हो सकती है "समारोह" और "मल्टीमैप के लिए" - यद्यपि आपको HashMap> subscibersCollection

के लिए इस्तेमाल करते हैं और कुछ इस तरह लागू कर सकते हैं:

import java.util.Collection; 
import com.google.common.collect.ArrayListMultimap; 
import com.google.common.base.Function; 

public class EventService { 

    ArrayListMultimap<String, Function<Object, Void>> subscibersCollection; 

    private static EventService instance = null; 

    private static final Object locker = new Object(); 

    private EventService() { 
     subscibersCollection = ArrayListMultimap.create(); 
    } 

    public static EventService getInstance() { 
     if (instance == null) { 
      synchronized (locker) { 
       if (instance == null) { 
        instance = new EventService(); 
       } 
      } 
     } 
     return instance; 
    } 

    /** 
    * Subscribe to the notification, and provide the callback functions in case 
    * notification is raised. 
    * 
    * @param notification 
    *   - notification name 
    * @param func 
    *   - function to apply when notification is raised 
    */ 
    public void addSubscription(String notification, Function<Object, Void> func) { 
     synchronized (subscibersCollection) { 
      if (!subscibersCollection.containsEntry(notification, func)) { 
       subscibersCollection.put(notification, func); 
      } 
     } 
    } 

    /** 
    * Remove subscription from notification 
    */ 
    public void removeSubscription(String notification, 
      Function<Object, Void> func) { 
     synchronized (subscibersCollection) { 
      subscibersCollection.remove(notification, func); 
     } 
    } 

    /** 
    * raise notification for all its subscribers 
    * 
    * @param notification 
    *   - notification name 
    * @param data 
    *   - update data 
    */ 
    public void publish(String notification, Object data) { 
     Collection<Function<Object, Void>> observableList = subscibersCollection 
       .get(notification); 
     for (Function<Object, Void> func : observableList) { 
      func.apply(data); 
     } 
    } 
} 
2

Behlul जवाब के आधार पर, मैं बनाने के लिए कोड बदलने यह आईओएस NSNotificationCenter के करीब है।

एक और बात: सूचनाएं

package com.oxygen.utils; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 

import android.os.Handler; 

public class NotificationCenter { 

//---------------- event type list --------------------- 

    public static enum NotificationID{ 
     IMAGES_CACHE_READY 
    } 


//---------------- singelton ---------------------------  

     private static NotificationCenter instance = null; 

     private NotificationCenter() { observables = new HashMap<NotificationID, MyObservable>(); } 

     public static synchronized NotificationCenter singelton() { 
      if (instance == null) { 
         instance = new NotificationCenter(); 
      } 
      return instance; 
     } 

//------------------------------------------- 

       public class Notification { 

        private Object poster; // the object that post the event 
        private Object info; // event specific data 
        private NotificationID id;  // event name 

        public Notification(Object poster, NotificationID id, Object info) { 
         super(); 
         this.poster = poster; 
         this.info = info; 
         this.id = id; 
        } 

        public Object getPoster() { 
         return poster; 
        } 

        public Object getInfo() { 
         return info; 
        } 

        public NotificationID getId() { 
         return id; 
        } 
       } 
     //------------------------------------------- 

       public interface Notifiable { 
        public void onNotification(Notification notify); 
       } 

//------------------------------------------- 

     protected class MyObservable { 
      List<Notifiable> observers = new ArrayList<Notifiable>(); 

      public MyObservable() { 
      } 

      public void addObserver(Notifiable observer) { 
       if (observer == null) { 
        throw new NullPointerException("observer == null"); 
       } 
       synchronized (this) { 
        if (!observers.contains(observer)) 
         observers.add(observer); 
       } 
      } 

      public int countObservers() { 
       return observers.size(); 
      } 

      public synchronized void deleteObserver(Notifiable observer) { 
       observers.remove(observer); 
      } 

      public synchronized void deleteObservers() { 
       observers.clear(); 
      } 

      public void notifyObservers(Notification notify) { 
       int size = 0; 
       Notifiable[] arrays = null; 
       synchronized (this) { 
         size = observers.size(); 
         arrays = new Notifiable[size]; 
         observers.toArray(arrays); 
       } 
       if (arrays != null) { 
        for (Notifiable observer : arrays) { 
         observer.onNotification(notify); 
        } 
       } 
      } 
     } 

//------------------------------------------- 

     HashMap<NotificationID, MyObservable > observables; 

     public void addObserver(NotificationID id, Notifiable observer) { 
      MyObservable observable = observables.get(id); 
      if (observable==null) { 
       observable = new MyObservable(); 
       observables.put(id, observable); 
      } 
      observable.addObserver(observer); 
     } 

     public void removeObserver(NotificationID id, Notifiable observer) { 
      MyObservable observable = observables.get(id); 
      if (observable!=null) {   
       observable.deleteObserver(observer); 
      } 
     } 

     public void removeObserver(Notifiable observer) { 
      for (MyObservable observable : observables.values()) { 
       if (observable!=null) {   
        observable.deleteObserver(observer); 
       }  
      } 
     } 

     public void postNotification(final Object notificationPoster, final NotificationID id, final Object notificationInfo) { 

      final MyObservable observable = observables.get(id); 
      if (observable!=null) { 

       // notification post to the maim (UI) thread  
       // Get a handler that can be used to post to the main thread 
       Handler mainHandler = new Handler(AppContext.get().getMainLooper()); 

       Runnable myRunnable = new Runnable() { 

        @Override 
        public void run() { 
         observable.notifyObservers(new Notification(notificationPoster, id, notificationInfo)); 
        } 
       }; 

       mainHandler.post(myRunnable); 
      } 
     } 
} 

श्रोता नमूना मुख्य थ्रेड पर सक्रिय होगा:

public class CustomGridViewAdapter extends ArrayAdapter<Category> implements Notifiable { 
    int layoutResourceId; 

    public CustomGridViewAdapter(Context context, int layoutResourceId) { 
     super(context, layoutResourceId); 
     this.layoutResourceId = layoutResourceId; 

     loadCategories(false); 
     NotificationCenter.singelton().addObserver(NotificationID.IMAGES_CACHE_READY, this); 
    } 

    public void onDestroy() { 
     NotificationCenter.singelton().removeObserver(this);    
    } 

    @Override 
    public void onNotification(Notification notify) { 
     switch (notify.getId()) { 
     case IMAGES_CACHE_READY: 
      loadCategories(true); 
      break; 
     } 
    } 
... 
} 
6

मैं एक ही wondrings था .. इसलिए मैं यह लिखा:

public class NotificationCenter { 

    //static reference for singleton 
    private static NotificationCenter _instance; 

    private HashMap<String, ArrayList<Runnable>> registredObjects; 

    //default c'tor for singleton 
    private NotificationCenter(){ 
     registredObjects = new HashMap<String, ArrayList<Runnable>>(); 
    } 

    //returning the reference 
    public static synchronized NotificationCenter defaultCenter(){ 
     if(_instance == null) 
      _instance = new NotificationCenter(); 
     return _instance; 
    } 

    public synchronized void addFucntionForNotification(String notificationName, Runnable r){ 
     ArrayList<Runnable> list = registredObjects.get(notificationName); 
     if(list == null) { 
      list = new ArrayList<Runnable>(); 
      registredObjects.put(notificationName, list); 
     } 
     list.add(r); 
    } 

    public synchronized void removeFucntionForNotification(String notificationName, Runnable r){ 
     ArrayList<Runnable> list = registredObjects.get(notificationName); 
     if(list != null) { 
      list.remove(r); 
     } 
    } 

    public synchronized void postNotification(String notificationName){ 
     ArrayList<Runnable> list = registredObjects.get(notificationName); 
     if(list != null) { 
      for(Runnable r: list) 
       r.run(); 
     } 
    } 

} 

और इसके लिए उपयोग होगा:

NotificationCenter.defaultCenter().addFucntionForNotification("buttonClick", new Runnable() { 
     @Override 
     public void run() { 
      Toast.makeText(MainActivity.this, "Hello There", Toast.LENGTH_LONG).show(); 
     } 
    }); 

इंटरफ़ेस को यथासंभव आईओएस के समान बनाने की कोशिश की, लेकिन सरल (कोई ऑब्जेक्ट पंजीकरण आवश्यक नहीं है)।

उम्मीद है कि मदद करता है :)

+1

बहुत बेहतर समाधान है। – pstoppani

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