如何构建App消息中心
- 主要涉及到的类
- LauncherApplication.java
- MsgCenter.java
- MsgUtil
- MsgPackage
- MsgEvent
- LauncherApplication.java
这里重写了android的Application类,同时定义了一个公有的静态的消息变量sMsgCenter,然后在init中初始化:
public static MsgCenter sMsgCenter;
public static Handler sHandler;
public static void init(Application activity) {
// 初始化默认值
sAppState = AppStateID.CREATE;
sMsgCenter = new MsgCenter(); // 初始化sMsgCenter静态变量
- MsgCenter.java
上面只是初始化了消息中心,那么怎么实现消息时间的绑定和运行呢?
MsgCenter类中有一个私有变量mListeners和三个方法bindListener,unbindListener,raiseMsg分别用来保存需要监听的事件(一个消息对应一个事件组Set),绑定消息事件,解绑消息事件,发送消息执行绑定的事件。
public class MsgCenter {
private Map<Object, Set<WeakReference<IMsgListener>>> mListeners =
new HashMap<Object, Set<WeakReference<IMsgListener>>>();
private static final String TAG = "Launcher*MsgCenter";
public void bindListener(Object event, IMsgListener listener) {
if (null==event || null==listener) {
return;
}
// 获取所有绑定某个事件的监听处理方法
Set<WeakReference<IMsgListener>> listenerLink = mListeners.get(event);
// 如果某个事件原先在队列中没有任何需要处理的程序,就直接在列表中增加该事件组
if (null == listenerLink) {
listenerLink = new HashSet<WeakReference<IMsgListener>>();
listenerLink.add(new WeakReference<IMsgListener>(listener));
mListeners.put(event, listenerLink);
} else {
// 如果已经有相应的事件类型,判断该事件类型中是否已经存在相应的监听程序,存在,break;不存在就添加该监听程序。
IMsgListener temp = null;
boolean exist = false;
for (WeakReference<IMsgListener> obj : listenerLink) {
temp = obj.get();
if (listener.equals(temp)) {
exist = true;
break;
}
}
if (!exist) {
listenerLink.add(new WeakReference<IMsgListener>(listener));
}
}
}
public void unbindListener(Object event, Object listener) {
if (null==event || null==listener) {
return;
}
Set<WeakReference<IMsgListener>> listenerLink = mListeners.get(event);
if (null != listenerLink) {
WeakReference<IMsgListener> exist = null;
IMsgListener temp = null;
for (WeakReference<IMsgListener> obj : listenerLink) {
temp = obj.get();
if (listener.equals(temp)) {
exist = obj;
break;
}
}
if (null != exist) {
listenerLink.remove(exist);
}
}
}
// 通知所有某个事件类型的监听程序执行
public void raiseMsg(MsgPackage msg) {
if (null==msg || null==msg.event) {
return;
}
Set<WeakReference<IMsgListener>> listenerLink = mListeners.get(msg.event);
// 如果存在事件类型,获取所有监听程序,逐个执行
if (null != listenerLink) {
IMsgListener temp = null;
LogHelper.debugLog(TAG, "MsgCenter raisemsgId-->"+msg.event);
WeakReference<IMsgListener>[] list = new WeakReference[listenerLink.size()];
listenerLink.toArray(list);
for (WeakReference<IMsgListener> li:list) {
if( li!=null ){
temp = li.get();
if (null != temp) {
// 这里我们看到调用每个监听对象的onRaised方法
temp.onRaised(msg);
}
}
}
}
}
}
- MsgUtil.java
一个app进程只有一个消息中心,MsgUtil类就用来管理整个消息中心,里面有两个静态方法raiseMsg和bindListener调用全局变量LauncherApplication.sMsgCenter来发送事件消息和绑定事件监听。
public class MsgUtil {
public static void raiseMsg(MsgPackage msg) {
LauncherApplication.sMsgCenter.raiseMsg(msg);
}
public static void bindListener(MsgEvent event, IMsgListener listener) {
LauncherApplication.sMsgCenter.bindListener(event, listener);
}
}
- MsgPackage.java
MsgPackage结构如下
public class MsgPackage {
public Object event;
public Object sender;
public MsgPackage(Object event, Object sender) {
this.event = event;
this.sender = sender;
}
}
- MsgEvent.java
MsgEvent中枚举了一些列事件的值
public enum MsgEvent {
/**
* 应用状态变化
*/
APP_STATE,
/**
* 导航栏焦点变化
*/
NAVI_FOCUS_CHANGED,
/**
* 内容区焦点变化
*/
CONTENT_FOCUS_CHANGED,
从上面的分析我们就该知道怎么使用,如果需要监听某个事件,我们只要绑定一个监听程序就可以,例如FoundModuleView.java中对有线网络连接的监听:
private void init() {
// mRunnableRequest.run();
MsgUtil.bindListener(MsgEvent.APP_STATE, mListenerAppState);
MsgUtil.bindListener(MsgEvent.NETWORK_STATE_UPDATE, mListenerConnected);
MsgUtil.bindListener(MsgEvent.WHALEY_STANDBY_ON_OR_OFF, mStandbtStateListener);
}
private IMsgListener mListenerConnected = new IMsgListener() {
@Override
public boolean onRaised(MsgPackage msg) {
NetworkPackage info = (NetworkPackage) msg;
switch (info.id) {
case UNCONNECT:
break;
default:
if (!mIsRequesting && null == mNewData) {
LogHelper.debugLog(TAG, "163: connected");
mRunnableRequest.run();
}
break;
}
return false;
}
};