Skip to content Skip to sidebar Skip to footer

Equivalent Of Ios Nsnotificationcenter In Android?

Is there an equivalent of the iOS class NSNotificationCenter in Android ? Are there any libraries or useful code available to me ?

Solution 1:

In Android there is not a central notification center as in ios. But you can basically use Observable and Observer objects to achieve your task.

You can define a class like something below, just modify it for singleton use and add synchronized for concurrent use but the idea is the same:

publicclassObservingService {
    HashMap<String, Observable> observables;

    publicObservingService() {
        observables = newHashMap<String, Observable>();
    }

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

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

    publicvoidpostNotification(String notification, Objectobject) {
        Observable observable = observables.get(notification);
        if (observable!=null) {
            observable.setChanged();
            observable.notifyObservers(object);
        }
    }
}

Solution 2:

Take a look at the Otto event bus from Square:

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

It has essentially the same features as NSNotificationCenter but thanks to annotations and static typing it is easier to follow the dependencies of components and paths that events follow. It's much simpler to use than the stock Android broadcast API, IMO.

Solution 3:

i had the same wondrings.. so i wrote this:

publicclassNotificationCenter {

    //static reference for singletonprivatestaticNotificationCenter _instance;

    privateHashMap<String, ArrayList<Runnable>> registredObjects;

    //default c'tor for singletonprivateNotificationCenter(){
        registredObjects = newHashMap<String, ArrayList<Runnable>>();
    }

    //returning the referencepublicstatic synchronized NotificationCenterdefaultCenter(){
        if(_instance == null)
            _instance = newNotificationCenter();
        return _instance;
    }

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

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

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

}

and a usage for this will be:

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

tried to make the interface as similar to IOS as possible, but simpler (no object registration needed).

hope that helps:)

Solution 4:

If you don't want to use Observer - it can be problematic in cases you want a Fragment to be your Observer cause you can't extend more then one class- You can use google's Guava Library (https://code.google.com/p/guava-libraries/) for "Function" and "Multimap" - although you can use as well HashMap> for the subscibersCollection

and implement something like this:

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

publicclassEventService {

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

    privatestaticEventService instance = null;

    privatestatic final Object locker = newObject();

    privateEventService() {
        subscibersCollection = ArrayListMultimap.create();
    }

    publicstaticEventServicegetInstance() {
        if (instance == null) {
            synchronized (locker) {
                if (instance == null) {
                    instance = newEventService();
                }
            }
        }
        return instance;
    }

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

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

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

Solution 5:

On the basis of Behlül answer, I change the code to make it closer to iOS NSNotificationCenter.

Another thing: the notifications will fire on the main thread

package com.oxygen.utils;

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

import android.os.Handler;

publicclassNotificationCenter {

//---------------- event type list ---------------------publicstaticenumNotificationID{
        IMAGES_CACHE_READY
    } 


//---------------- singelton ---------------------------    privatestaticNotificationCenterinstance=null;

        privateNotificationCenter() { observables = newHashMap<NotificationID, MyObservable>();   }

        publicstaticsynchronized NotificationCenter singelton() {
            if (instance == null) {
                        instance = newNotificationCenter ();
            }
            return instance;
        }

//-------------------------------------------publicclassNotification {

                    private Object poster;  // the object that post the eventprivate Object info;    // event specific data private NotificationID id;      // event namepublicNotification(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;
                    }
                }
        //-------------------------------------------publicinterfaceNotifiable {
                    publicvoidonNotification(Notification notify);
                }

//-------------------------------------------protectedclassMyObservable {
            List<Notifiable> observers = newArrayList<Notifiable>();

            publicMyObservable() {
            }

            publicvoidaddObserver(Notifiable observer) {
                if (observer == null) {
                    thrownewNullPointerException("observer == null");
                }
                synchronized (this) {
                    if (!observers.contains(observer))
                        observers.add(observer);
                }
            }

            publicintcountObservers() {
                return observers.size();
            }

            publicsynchronizedvoiddeleteObserver(Notifiable observer) {
                observers.remove(observer);
            }

            publicsynchronizedvoiddeleteObservers() {
                observers.clear();
            }

            publicvoidnotifyObservers(Notification notify) {
                intsize=0;
                Notifiable[] arrays = null;
                synchronized (this) {
                        size = observers.size();
                        arrays = newNotifiable[size];
                        observers.toArray(arrays);
                }
                if (arrays != null) {
                    for (Notifiable observer : arrays) {
                        observer.onNotification(notify);
                    }
                }
            }
        }

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

        HashMap<NotificationID, MyObservable > observables;

        publicvoidaddObserver(NotificationID id, Notifiable observer) {
            MyObservableobservable= observables.get(id);
            if (observable==null) {
                observable = newMyObservable ();
                observables.put(id, observable);
            }
            observable.addObserver(observer);
        }

        publicvoidremoveObserver(NotificationID id, Notifiable observer) {
            MyObservableobservable= observables.get(id);
            if (observable!=null) {         
                observable.deleteObserver(observer);
            }
        }

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

        publicvoidpostNotification(final Object notificationPoster, final NotificationID id, final Object notificationInfo) {

            finalMyObservableobservable= 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 threadHandlermainHandler=newHandler(AppContext.get().getMainLooper());

                RunnablemyRunnable=newRunnable() {

                    @Overridepublicvoidrun() {
                        observable.notifyObservers(newNotification(notificationPoster, id, notificationInfo) );
                    }
                };

                mainHandler.post(myRunnable);
            }
        }
}

Listener sample:

publicclassCustomGridViewAdapterextendsArrayAdapter<Category>  implementsNotifiable {
    int layoutResourceId;

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

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

    publicvoidonDestroy() {
        NotificationCenter.singelton().removeObserver(this);            
    }

    @OverridepublicvoidonNotification(Notification notify) {
        switch (notify.getId()) {
        case IMAGES_CACHE_READY:
            loadCategories(true);
            break;
        }
    }
...
}

Post a Comment for "Equivalent Of Ios Nsnotificationcenter In Android?"