观察者模式取代BroadCast

/*
 * This is the source code of Telegram for Android v. 1.3.2.
 * It is licensed under GNU GPL v. 2 or later.
 * You should have received a copy of the license in this archive (see LICENSE).
 *
 * Copyright Nikolai Kudashov, 2013.
 */

package org.telegram.android;

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

public class NotificationCenter {

    private static int totalEvents = 1;

    public static final int didReceivedNewMessages = totalEvents++;
    public static final int updateInterfaces = totalEvents++;
    public static final int dialogsNeedReload = totalEvents++;
    public static final int closeChats = totalEvents++;
    public static final int messagesDeleted = totalEvents++;
    public static final int messagesRead = totalEvents++;
    public static final int messagesDidLoaded = totalEvents++;
    public static final int messageReceivedByAck = totalEvents++;
    public static final int messageReceivedByServer = totalEvents++;
    public static final int messageSendError = totalEvents++;
    public static final int contactsDidLoaded = totalEvents++;
    public static final int chatDidCreated = totalEvents++;
    public static final int chatDidFailCreate = totalEvents++;
    public static final int chatInfoDidLoaded = totalEvents++;
    public static final int mediaDidLoaded = totalEvents++;
    public static final int mediaCountDidLoaded = totalEvents++;
    public static final int encryptedChatUpdated = totalEvents++;
    public static final int messagesReadedEncrypted = totalEvents++;
    public static final int encryptedChatCreated = totalEvents++;
    public static final int userPhotosLoaded = totalEvents++;
    public static final int removeAllMessagesFromDialog = totalEvents++;
    public static final int notificationsSettingsUpdated = totalEvents++;
    public static final int pushMessagesUpdated = totalEvents++;
    public static final int blockedUsersDidLoaded = totalEvents++;
    public static final int openedChatChanged = totalEvents++;
    public static final int hideEmojiKeyboard = totalEvents++;
    public static final int stopEncodingService = totalEvents++;
    public static final int didCreatedNewDeleteTask = totalEvents++;
    public static final int mainUserInfoChanged = totalEvents++;
    public static final int privacyRulesUpdated = totalEvents++;
    public static final int updateMessageMedia = totalEvents++;
    public static final int recentImagesDidLoaded = totalEvents++;
    public static final int replaceMessagesObjects = totalEvents++;
    public static final int didSetPasscode = totalEvents++;
    public static final int didSetTwoStepPassword = totalEvents++;
    public static final int screenStateChanged = totalEvents++;
    public static final int appSwitchedToForeground = totalEvents++;
    public static final int didLoadedReplyMessages = totalEvents++;
    public static final int newSessionReceived = totalEvents++;
    public static final int didReceivedWebpages = totalEvents++;
    public static final int didReceivedWebpagesInUpdates = totalEvents++;

    public static final int httpFileDidLoaded = totalEvents++;
    public static final int httpFileDidFailedLoad = totalEvents++;

    public static final int messageThumbGenerated = totalEvents++;

    public static final int wallpapersDidLoaded = totalEvents++;
    public static final int closeOtherAppActivities = totalEvents++;
    public static final int didUpdatedConnectionState = totalEvents++;
    public static final int didReceiveSmsCode = totalEvents++;
    public static final int emojiDidLoaded = totalEvents++;
    public static final int appDidLogout = totalEvents++;

    public static final int FileDidUpload = totalEvents++;
    public static final int FileDidFailUpload = totalEvents++;
    public static final int FileUploadProgressChanged = totalEvents++;
    public static final int FileLoadProgressChanged = totalEvents++;
    public static final int FileDidLoaded = totalEvents++;
    public static final int FileDidFailedLoad = totalEvents++;
    public static final int FilePreparingStarted = totalEvents++;
    public static final int FileNewChunkAvailable = totalEvents++;
    public static final int FilePreparingFailed = totalEvents++;

    public static final int audioProgressDidChanged = totalEvents++;
    public static final int audioDidReset = totalEvents++;
    public static final int recordProgressChanged = totalEvents++;
    public static final int recordStarted = totalEvents++;
    public static final int recordStartError = totalEvents++;
    public static final int recordStopped = totalEvents++;
    public static final int screenshotTook = totalEvents++;
    public static final int albumsDidLoaded = totalEvents++;
    public static final int audioDidSent = totalEvents++;
    public static final int audioDidStarted = totalEvents++;
    public static final int audioRouteChanged = totalEvents++;

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

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

    private int broadcasting = 0;

    private static volatile NotificationCenter Instance = null;
    public static NotificationCenter getInstance() {
        NotificationCenter localInstance = Instance;
        if (localInstance == null) {
            synchronized (NotificationCenter.class) {
                localInstance = Instance;
                if (localInstance == null) {
                    Instance = localInstance = new NotificationCenter();
                }
            }
        }
        return localInstance;
    }

    public interface NotificationCenterDelegate {
        void didReceivedNotification(int id, Object... args);
    }

    public void postNotificationName(int id, Object... args) {
        synchronized (observers) {
            broadcasting++;
            ArrayList<Object> objects = observers.get(id);
            if (objects != null) {
                for (Object obj : objects) {
                    ((NotificationCenterDelegate)obj).didReceivedNotification(id, args);
                }
            }
            broadcasting--;
            if (broadcasting == 0) {
                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 != 0) {
                addAfterBroadcast.put(id, observer);
                return;
            }
            ArrayList<Object> objects = observers.get(id);
            if (objects == null) {
                observers.put(id, (objects = new ArrayList<>()));
            }
            if (objects.contains(observer)) {
                return;
            }
            objects.add(observer);
        }
    }

    public void removeObserver(Object observer, int id) {
        synchronized (observers) {
            if (broadcasting != 0) {
                removeAfterBroadcast.put(id, observer);
                return;
            }
            ArrayList<Object> objects = observers.get(id);
            if (objects != null) {
                objects.remove(observer);
                if (objects.size() == 0) {
                    observers.remove(id);
                }
            }
        }
    }
}
时间: 2024-10-04 22:23:09

观察者模式取代BroadCast的相关文章

IPv6 简介以及位址介绍

IPv6 简介 IPv6(IP版本6)是互联网通讯协议(Internet Protocol,简称IP)的新版本,它被设计来取代IPv4.并且针对当初设计IPv4时没有考虑到的问题做了以下改进: 扩展地址空间  IPv6将IP地址长度从32 bits扩展到128 bits,其主要目的是支持更多层的阶层式的路由架构,更大的地址空间(IPv6的地址不再有耗尽之虑),并且提供更简单的自动组态配置.在multicast address中新增 "scope" 字段来提升multicast rout

IOS设计模式之三(适配器模式,观察者模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么错误,请与我联系谢谢. 适配器(Adapter)模式 适配器可以让一些接口不兼容的类一起工作.它包装一个对象然后暴漏一个标准的交互接口. 如果你熟悉适配器设计模式,苹果通过一个稍微不同的方式来实现它-苹果使用了协议的方式来实现.你可能已经熟悉UITableViewDelegat

【读书笔记】读《JavaScript设计模式》之观察者模式

一.定义 在事件驱动的环境中,比如浏览器这种持续寻求用户关注的环境中,观察者模式(又名发布者-订阅者(publisher-subscripber)模式)是一种管理人与其任务之间的关系(确切地讲,是对象及其行为和状态之间的关系)的得力工具.用JavaScript的话来说,这种模式的实质就是你可以对程序中某个对象的状态进行观察,并且在其发生改变时能够得到通知. 二.例子 我们需要一个发布者的构造函数,它为该实例定义了一个类型为数组的属性,用来保存订阅者的引用. function Publisher(

观察者模式和订阅/发布者模式(转)

在翻阅资料的时候,有人把观察者(Observer)模式等同于发布(Publish)/订阅(Subscribe)模式,也有人认为这两种模式还是存在差异,而我认为确实是存在差异的,本质上的区别是调度的地方不同. 观察者模式 比较概念的解释是,目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口.具体观察者和具体目标继承各自的基类,然后具体观察者把自己注册到具体目标里,在具体目标发生变化时候,调度观察者的更新方法. 比如有个“天气中心”的具体目标A,专门监听天气变化,而有个显示天气的

利用观察者模式来对程序模块进行解耦

这段时间在对我们项目的代码进行重构,发现我们以往开发软件的时候耦合度非常高, 最严重的是很难对软件进行扩展和删减,现在对软件进行扩展的功能成本非常大 比如我们有一个模块a,当到打一定的时间,或者说条件后,需要调用它: function() { function_a1() function_a2() function_a3() } 这个时候软件还好,但是随着时间的增加,你需要加入b,c,d,e的功能,代码将会非常长,而且如果有时候我们需要阉割一些功能,或者说,我们需要增加一些功能,但是这个功能只是

【转】Cocos2d - 观察者模式NotificationCenter

http://shahdza.blog.51cto.com/2410787/1611575 [唠叨] 观察者模式 也叫订阅/发布(Subscribe/Publish)模式,是 MVC( 模型-视图-控制器)模式的重要组成部分. 举个例子:邮件消息的订阅.  比如我们对51cto的最新技术动态频道进行了消息订阅.那么每隔一段时间,有新的技术动态出来时,51cto网站就会将新技术的新闻自动发送邮件给每一个订阅了该消息的用户.当然你如果以后不想再收到这类邮件的话,你可以申请退订消息. 而在我们的游戏中

设计模式整理_观察者模式

观察者模式定义了对象之间的一对多的依赖,这样一来,当一个对象的状态发生改变的时候,它的所有依赖者都会收到通知,并且进行更新. 被观测的对象称为主题(Subject),观察被观测的对象的对象称为观察者(Observer). 现实中的观察者模式:例如报纸的订阅.不同人(Observer)向报社(Subject)订购报纸,当报社出品了新的报纸的时候,将会通知它的订阅者,送报纸.中途订阅者可以取消订阅,此时报社就不再给他报纸.但是只要报社一直存在,就可以有人订阅报纸. 在JavaGUI中,就有观察者模式

观察者模式在Android开发场景中运用之通过Java源码分析(一)

对于观察者,很多开发者并不陌生,在日常开发过程中,这也是一个非常常见的设计模式,尤其是Android小伙伴,很多人都知道broadcast就是一个典型的观察者模式,还有最近很火的rxjava,响应式编程中,观察者模式扮演着一个很重要的角色,但观察者模式具体是怎么样运转的,部分小伙伴就有点模糊了. 先从日常生活中一个例子开始说起,在看电视的过程中,我们经常看到一些抗日神剧中有这么一个剧情,鬼子进村,在进村的过程中,总会有一些一些人通风报信,然后通知村里的人能躲的躲,能藏的藏,能跑的跑,或者中路再搞

cocos2dx[3.2](21)——观察者模式NotificationCenter

[唠叨] 观察者模式 也叫订阅/发布(Subscribe/Publish)模式,是 MVC( 模型-视图-控制器)模式的重要组成部分. 举个例子:邮件消息的订阅.  比如我们对51cto的最新技术动态频道进行了消息订阅.那么每隔一段时间,有新的技术动态出来时,51cto网站就会将新技术的新闻自动发送邮件给每一个订阅了该消息的用户.当然你如果以后不想再收到这类邮件的话,你可以申请退订消息. 而在我们的游戏中,也是需要这样的订阅/发布模式的.在参考文献<设计模式--观察者模式>中给出了一个非常典型