关闭

Android观察者模式NotificationCenter,可以试试替换BroadCastReceiver

标签: Android-广播
517人阅读 评论(0) 收藏 举报
分类:

1、NotificationCenter

NotificationCenter是一个单例类,即与Director类一样。它主要用来管理订阅/发布消息的中心。

单例类的使用:通过 NotificationCenter.getInstance() 来获取单例对象。

它有三个核心函数和一个观察者数组:

订阅消息: addObserver()。订阅感兴趣的消息。

发布消息: postNotification()。发布消息。

退订消息: removeObserver()。不感兴趣了,就退订。

观察者数组: _observers

而观察者对象是NotificationObserver类,它的作用就是:将订阅的消息与相应的订阅者、订阅者绑定的回调函数联系起来。

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

/**
 * @Classname NotificationCenter.java
 *
 * @author chewei
 *
 * @Description 观察者模式
 *
 * @Parameter 
 */
public class NotificationCenter {

    final private HashMap<Integer, ArrayList<Object>> observers = new HashMap<Integer, ArrayList<Object>>();

    final private HashMap<Integer, Object> removeAfterBroadcast = new HashMap<Integer, Object>();
    final private HashMap<Integer, Object> addAfterBroadcast = new HashMap<Integer, Object>();

    private boolean broadcasting = false;

    private static volatile NotificationCenter Instance = null;
    public static NotificationCenter getInstance() {//单例模式创建NotificationCenter
        NotificationCenter localInstance = Instance;
        if (localInstance == null) {
            synchronized (NotificationCenter.class) {
                localInstance = Instance;
                if (localInstance == null) {
                    Instance = localInstance = new NotificationCenter();
                }
            }
        }
        return localInstance;
    }

    public interface NotificationCenterDelegate {//接口用于通知观察者领取信息
        public abstract void didReceivedNotification(int id, Object... args);
    }

    public void postNotificationName(int id, Object... args) {//被观察者发送消息
        synchronized (observers) {
            broadcasting = true;
            ArrayList<Object> objects = observers.get(id);
            if (objects != null) {
                for (Object obj : objects) 
                {   
                    ((NotificationCenterDelegate)obj).didReceivedNotification(id, args);
                }
            }
            broadcasting = false;
            if (!removeAfterBroadcast.isEmpty()) {
                for (HashMap.Entry<Integer, Object> entry : removeAfterBroadcast.entrySet()) {
                    removeObserver(entry.getValue(), entry.getKey());
                }
                removeAfterBroadcast.clear();
            }
            if (!addAfterBroadcast.isEmpty()) {
                for (HashMap.Entry<Integer, Object> entry : addAfterBroadcast.entrySet()) {
                    addObserver(entry.getValue(), entry.getKey());
                }
                addAfterBroadcast.clear();
            }
        }
    }

    public void addObserver(Object observer, int id) {//注册
        synchronized (observers) {
            if (broadcasting) {
                addAfterBroadcast.put(id, observer);
                return;
            }
            ArrayList<Object> objects = observers.get(id);
            if (objects == null) 
            {   
                observers.put(id, (objects = new ArrayList<Object>()));
            }
            if (objects.contains(observer)) {
                return;
            }
            //if( id == MessagesController.contactsDidLoaded)
                //FileLog.d("emm", "postNotificationName addObserver");
            objects.add(observer);
        }
    }

    public void removeObserver(Object observer, int id) {//移除
        synchronized (observers) {
            if (broadcasting) {
                removeAfterBroadcast.put(id, observer);
                return;
            }
            ArrayList<Object> objects = observers.get(id);
            if (objects != null) {
                objects.remove(observer);
                if (objects.size() ==   0) {
                    observers.remove(id);
                }
            }
        }
    }
}

(1)观察者需要implements NotificationCenterDelegate
(2)在界面开始(一般放在Oncreate方法里)和销毁里进行注册和移除(第一个参数一般传该acitivty对象(this))
(3)在didReceivedNotification里面判断标识(id)来进行处理object
(4)剩下的就是获取该单利对象发送消息了,哪块发送就写在哪块postNotificationName,这块的标识和注册、销毁里面的一样

个人感觉这个用起来感觉比Android的BroadCastRecevier好用简洁

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21984次
    • 积分:655
    • 等级:
    • 排名:千里之外
    • 原创:41篇
    • 转载:20篇
    • 译文:0篇
    • 评论:6条
    文章分类
    最新评论