Android之WIFI-WifiMonitor分析
2022-02-17 本文已影响0人
锄禾豆
概述
WifiMonitor负责监听wpa_supplicant发送的数据,并将数据分发给个监听者
详细
1.怎么监听wpa_supplicant发送过来的数据
private class MonitorThread extends Thread {
private final LocalLog mLocalLog;
public MonitorThread(LocalLog localLog) {
super("WifiMonitor");
mLocalLog = localLog;
}
public void run() {
if (DBG) {
Log.d(TAG, "MonitorThread start with mConnected=" + mConnected);
}
//noinspection InfiniteLoopStatement
for (;;) {
if (!mConnected) {
if (DBG) Log.d(TAG, "MonitorThread exit because mConnected is false");
break;
}
String eventStr = mWifiNative.waitForEvent();//监听wpa_supplicant发送的数据
// Skip logging the common but mostly uninteresting events
if (!eventStr.contains(BSS_ADDED_STR) && !eventStr.contains(BSS_REMOVED_STR)) {
if (DBG) Log.d(TAG, "Event [" + eventStr + "]");
mLocalLog.log("Event [" + eventStr + "]");
}
if (dispatchEvent(eventStr)) {
if (DBG) Log.d(TAG, "Disconnecting from the supplicant, no more events");
break;
}
}
}
}
2.怎么将数据分发给监听者?
1)监听者是怎么注册进来的?
private final Map<String, SparseArray<Set<Handler>>> mHandlerMap = new HashMap<>();
public synchronized void registerHandler(String iface, int what, Handler handler) {
SparseArray<Set<Handler>> ifaceHandlers = mHandlerMap.get(iface);
if (ifaceHandlers == null) {
ifaceHandlers = new SparseArray<>();
mHandlerMap.put(iface, ifaceHandlers);
}
Set<Handler> ifaceWhatHandlers = ifaceHandlers.get(what);
if (ifaceWhatHandlers == null) {
ifaceWhatHandlers = new ArraySet<>();
ifaceHandlers.put(what, ifaceWhatHandlers);
}
ifaceWhatHandlers.add(handler);
}
1)mHandlerMap是一个map。key\values,这个values是数组SparseArray<Set<Handler>>
2)SparseArray<Set<Handler>>是一个数组。kyes\values,这个values是集合Set<Handler>
这是三维代码。通过iface获取数组SparseArray,通过what获取handler集合。关键是监听者的handler做数据处理。也就是说,一个what不仅仅对应一个handler,而是对应多个handler
2)监听者处理数据
MonitorThread.run调用了dispatchEvent
private synchronized boolean dispatchEvent(String eventStr) {
······
if (dispatchEvent(eventStr, iface)) {
mConnected = false;
return true;
}
return false;
}
private boolean dispatchEvent(String eventStr, String iface) {
//1.根据eventStr和iface过滤有效数据
//2.关键点为sendMessage
}
private void sendMessage(String iface, Message message) {
SparseArray<Set<Handler>> ifaceHandlers = mHandlerMap.get(iface);//从mHandlerMap中获取iface数组
if (iface != null && ifaceHandlers != null) {
if (isMonitoring(iface)) {
boolean firstHandler = true;
Set<Handler> ifaceWhatHandlers = ifaceHandlers.get(message.what);//数组存在,则通过what获取handler集合
if (ifaceWhatHandlers != null) {
for (Handler handler : ifaceWhatHandlers) {//集中处理handler集合
if (firstHandler) {
firstHandler = false;
sendMessage(handler, message);
}
else {
sendMessage(handler, Message.obtain(message));
}
}
}
} else {
if (DBG) Log.d(TAG, "Dropping event because (" + iface + ") is stopped");
}
} else {
if (DBG) Log.d(TAG, "Sending to all monitors because there's no matching iface");
boolean firstHandler = true;
for (Map.Entry<String, SparseArray<Set<Handler>>> entry : mHandlerMap.entrySet()) {
if (isMonitoring(entry.getKey())) {
Set<Handler> ifaceWhatHandlers = entry.getValue().get(message.what);
for (Handler handler : ifaceWhatHandlers) {
if (firstHandler) {
firstHandler = false;
sendMessage(handler, message);
}
else {
sendMessage(handler, Message.obtain(message));
}
}
}
}
}
}
private void sendMessage(Handler handler, Message message) {
if (handler != null) {
message.setTarget(handler);//设置目标对象
message.sendToTarget();//发送给目标对象
}
}
总结
1.我们一般设置回调时,就是调用监听者的回调方法,而这里的监听处理就显着与众不同
2.因为它回调给的是目标对象的handler