import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.SparseArray;
import android.view.View;
import com.sintn.hera.shop.event.Event;
import com.sintn.utils.common.SystemCommonUtils;
import com.sintn.utils.core.EventManager;
/**
*
* @Description: 全局事件管理者
* @ClassName: AndroidEventManager
* @author wxl.sinto.cto
* @date 2014-10-21 下午2:37:34
*
*/
public class AndroidEventManager extends EventManager
{
private static AndroidEventManager sInstance;
public static AndroidEventManager getInstance()
{
if (sInstance == null)
{
sInstance = new AndroidEventManager();
}
return sInstance;
}
private static final int WHAT_EVENT_NOTIFY = 1;
private static final int WHAT_EVENT_RUN = 2;
private SparseArray<Event> codeToEventMap = new SparseArray<Event>();
private List<EventWrapper> eventWrappers = new LinkedList<EventWrapper>();
private Map<Event, Event> eventRunningMap = new ConcurrentHashMap<Event, Event>();
private List<Event> eventNotifyEvents = new LinkedList<Event>();
private boolean isEventNotifying;
private SparseArray<List<OnEventListener>> codeToEventListenerMap = new SparseArray<List<OnEventListener>>();
private SparseArray<List<OnEventListener>> codeToEventListenerAddCacheMap = new SparseArray<List<OnEventListener>>();
private SparseArray<List<OnEventListener>> codeToEventListenerRemoveCacheMap = new SparseArray<List<OnEventListener>>();
private boolean isMapListenerLock = false;
private SparseArray<OnEventListener> listenerUserOnceMap = new SparseArray<OnEventListener>();
private Map<Event, List<ParamWrapper>> eventToWaitRunParamMap = new ConcurrentHashMap<Event, List<ParamWrapper>>();
private static Handler handler = new Handler(Looper.getMainLooper())
{
@Override
public void handleMessage(Message msg)
{
final int nWhat = msg.what;
if (nWhat == WHAT_EVENT_RUN)
{
EventWrapper ew = (EventWrapper) msg.obj;
sInstance.runEvent(ew.mEvent, ew.mParams);
sInstance.recycleEventWrapper(ew);
} else if (nWhat == WHAT_EVENT_NOTIFY)
{
sInstance.doNotify((Event) msg.obj);
}
}
};
@Override
public void addEvent(Event event)
{
codeToEventMap.put(event.getEventCode(), event);
}
@Override
public void removeEvent(int nEventCode)
{
codeToEventMap.remove(nEventCode);
}
@Override
public void removeAllEvent()
{
codeToEventMap.clear();
}
@Override
public void postEvent(int nEventCode, long delayMillis, Object... params)
{
Event event = getEvent(nEventCode);
postEvent(event, delayMillis, params);
}
public void postEvent(int nEventCode, long delayMillis, View view, Object... params)
{
Event event = getEvent(nEventCode);
event.relationView = view;
postEvent(event, delayMillis, params);
}
@Override
public void postEvent(Event event, long delayMillis, Object... params)
{
if (event != null)
{
EventWrapper ew = obtainEventWrapper();
ew.set(event, params);
handler.sendMessageDelayed(handler.obtainMessage(WHAT_EVENT_RUN, ew), delayMillis);
}
}
private synchronized EventWrapper obtainEventWrapper()
{
if (eventWrappers.size() > 0)
{
EventWrapper ev = eventWrappers.get(0);
eventWrappers.remove(0);
return ev;
}
return new EventWrapper();
}
private synchronized void recycleEventWrapper(EventWrapper ew)
{
ew.clear();
eventWrappers.add(ew);
}
public void addEventListener(int nEventCode, OnEventListener listener, boolean bOnce)
{
if (isMapListenerLock)
{
addToListenerMap(codeToEventListenerAddCacheMap, nEventCode, listener);
} else
{
addToListenerMap(codeToEventListenerMap, nEventCode, listener);
}
if (bOnce)
{
listenerUserOnceMap.put(calculateHashCode(nEventCode, listener), listener);
}
}
public void removeEventListener(int nEventCode, OnEventListener listener)
{
if (isMapListenerLock)
{
addToListenerMap(codeToEventListenerRemoveCacheMap, nEventCode, listener);
} else
{
List<OnEventListener> listeners = codeToEventListenerMap.get(nEventCode);
if (listeners != null)
{
listeners.remove(listener);
}
}
}
private int calculateHashCode(int nEventCode, OnEventListener listener)
{
int nResult = nEventCode;
nResult = nResult * 29 + listener.hashCode();
return nResult;
}
/**
* 发送通知
*
* @param event
*/
private synchronized void doNotify(Event event)
{
isEventNotifying = true;
isMapListenerLock = true;
List<OnEventListener> list = codeToEventListenerMap.get(event.getEventCode());
if (list != null)
{
List<OnEventListener> listNeedRemove = null;
//轮询模式
for (OnEventListener listener : list)
{
listener.onEventRunEnd(event);
int nHashCode = calculateHashCode(event.getEventCode(), listener);
if (listenerUserOnceMap.get(nHashCode) != null)
{
listenerUserOnceMap.remove(nHashCode);
if (listNeedRemove == null)
{
listNeedRemove = new ArrayList<EventManager.OnEventListener>();
}
listNeedRemove.add(listener);
BaseApplication.getLogger().info("removeOnce Code:" + event.getEventCode() + " listener:" + listener);
}
}
if (listNeedRemove != null)
{
list.removeAll(listNeedRemove);
}
}
isMapListenerLock = false;
isEventNotifying = false;
if (codeToEventListenerAddCacheMap.size() > 0)
{
int nSize = codeToEventListenerAddCacheMap.size();
for (int nIndex = 0; nIndex < nSize; ++nIndex)
{
int nCode = codeToEventListenerAddCacheMap.keyAt(nIndex);
List<OnEventListener> listCache = codeToEventListenerAddCacheMap.get(nCode);
if (listCache.size() > 0)
{
List<OnEventListener> listeners = codeToEventListenerMap.get(nCode);
if (listeners == null)
{
listeners = new LinkedList<AndroidEventManager.OnEventListener>();
codeToEventListenerMap.put(nCode, listeners);
}
listeners.addAll(listCache);
}
}
codeToEventListenerAddCacheMap.clear();
}
if (codeToEventListenerRemoveCacheMap.size() > 0)
{
int nSize = codeToEventListenerRemoveCacheMap.size();
for (int nIndex = 0; nIndex < nSize; ++nIndex)
{
int nCode = codeToEventListenerRemoveCacheMap.keyAt(nIndex);
List<OnEventListener> listCache = codeToEventListenerRemoveCacheMap.get(nCode);
if (listCache.size() > 0)
{
List<OnEventListener> listeners = codeToEventListenerMap.get(nCode);
if (listeners != null)
{
listeners.removeAll(listCache);
}
}
}
codeToEventListenerRemoveCacheMap.clear();
}
if (eventNotifyEvents.size() > 0)
{
Event eventNotify = eventNotifyEvents.get(0);
eventNotifyEvents.remove(0);
handler.sendMessage(handler.obtainMessage(WHAT_EVENT_NOTIFY, eventNotify));
}
}
@Override
public Event runEvent(int nEventCode, Object... params)
{
Event event = getEvent(nEventCode);
return runEvent(event, params);
}
@Override
public Event runEvent(Event event, final Object... params)
{
if (event == null)
{
return null;
}
if (eventRunningMap.containsKey(event))
{
if (event.isWaitRunWhenRunning())
{
List<ParamWrapper> listParamWrapper = eventToWaitRunParamMap.get(event);
if (listParamWrapper == null)
{
listParamWrapper = Collections.synchronizedList(new LinkedList<ParamWrapper>());
eventToWaitRunParamMap.put(event, listParamWrapper);
}
listParamWrapper.add(new ParamWrapper(params));
}
return null;
}
eventRunningMap.put(event, event);
if (event.isAsyncRun())
{
final Event localEvent = event;
localEvent.onPreRun();
new Thread()
{
@Override
public void run()
{
try
{
if (SystemCommonUtils.isNetworkAvailable(BaseApplication.getApplication()))
{
synchronized (AndroidEventManager.class)
{
localEvent.run(params);
}
}
} catch (Exception e)
{
e.printStackTrace();
} finally
{
BaseApplication.getMainThreadHandler().post(new Runnable()
{
@Override
public void run()
{
onEventRunEnd(localEvent);
}
});
}
}
}.start();
} else
{
try
{
event.run(params);
} catch (Exception e)
{
e.printStackTrace();
}
onEventRunEnd(event);
}
return event;
}
private void addToListenerMap(SparseArray<List<OnEventListener>> map, int nEventCode, OnEventListener listener)
{
List<OnEventListener> listeners = map.get(nEventCode);
if (listeners == null)
{
listeners = new LinkedList<AndroidEventManager.OnEventListener>();
map.put(nEventCode, listeners);
}
listeners.add(listener);
}
protected void onEventRunEnd(Event event)
{
eventRunningMap.remove(event);
event.onRunEnd();
if (event.isNotifyAfterRun())
{
notifyEventRunEnd(event);
}
List<ParamWrapper> listParamWrapper = eventToWaitRunParamMap.get(event);
if (listParamWrapper != null)
{
if (listParamWrapper.size() > 0)
{
ParamWrapper param = listParamWrapper.get(0);
listParamWrapper.remove(param);
postEvent(event, 0, param.mParams);
if (listParamWrapper.size() == 0)
{
eventToWaitRunParamMap.remove(event);
}
}
}
}
private void notifyEventRunEnd(Event event)
{
if (isEventNotifying)
{
eventNotifyEvents.add(event);
} else
{
doNotify(event);
}
}
public Event getEvent(int nEventCode)
{
return codeToEventMap.get(nEventCode);
}
private static class EventWrapper
{
public Event mEvent;
public Object[] mParams;
public void set(Event event, Object... params)
{
mEvent = event;
mParams = params;
}
public void clear()
{
mEvent = null;
mParams = null;
}
}
private static class ParamWrapper
{
public Object[] mParams;
public ParamWrapper(Object[] params)
{
mParams = params;
}
}
}
单例模式创建对象没有定义私有的构造方法。。