16

AndroidにiOSクラスNSNotificationCenterに相当するものはありますか?私が利用できるライブラリや便利なコードはありますか?

4

5 に答える 5

21

Androidには、iOSのような中央通知センターはありません。ただし、基本的には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);
        }
    }
}
于 2012-04-26T04:46:51.720 に答える
9

スクエアからのオットーイベントバスを見てください:

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

NSNotificationCenterと基本的に同じ機能がありますが、注釈と静的型付けのおかげで、イベントがたどるコンポーネントとパスの依存関係を簡単にたどることができます。標準のAndroidブロードキャストAPIであるIMOよりもはるかに簡単に使用できます。

于 2012-12-20T10:00:20.180 に答える
9

私は同じ不思議を持っていた..だから私はこれを書いた:

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();
        }
    });

インターフェイスをできるだけIOSに似たものにしようとしましたが、よりシンプルになりました(オブジェクトの登録は必要ありません)。

お役に立てば幸いです:)

于 2015-06-11T14:55:16.560 に答える
2

オブザーバーを使用したくない場合-フラグメントをオブザーバーにしたい場合は問題が発生する可能性があります。これは、複数のクラスを拡張できないためです-googleのGuavaライブラリ(https://code.google)を使用できます。 com / p / guava-libraries /)「Function」および「Multimap」の場合-subscibersCollectionのHashMap>も使用できますが

次のようなものを実装します。

    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);
        }
    }
}
于 2013-06-06T08:38:18.523 に答える
2

Behlülの回答に基づいて、iOSNSNotificationCenterに近づくようにコードを変更します。

別のこと:通知はメインスレッドで発生します

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;
        }
    }
...
}
于 2014-03-20T15:08:37.487 に答える