Android之WIFI-WifiMonitor分析

概述

WifiMonitor負(fù)責(zé)監(jiān)聽wpa_supplicant發(fā)送的數(shù)據(jù),并將數(shù)據(jù)分發(fā)給個(gè)監(jiān)聽者

詳細(xì)
1.怎么監(jiān)聽wpa_supplicant發(fā)送過來的數(shù)據(jù)

    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();//監(jiān)聽wpa_supplicant發(fā)送的數(shù)據(jù)

                // 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.怎么將數(shù)據(jù)分發(fā)給監(jiān)聽者?
1)監(jiān)聽者是怎么注冊(cè)進(jìn)來的?

    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是一個(gè)map。key\values,這個(gè)values是數(shù)組SparseArray<Set<Handler>>
    2)SparseArray<Set<Handler>>是一個(gè)數(shù)組。kyes\values,這個(gè)values是集合Set<Handler>
    
    這是三維代碼。通過iface獲取數(shù)組SparseArray,通過what獲取handler集合。關(guān)鍵是監(jiān)聽者的handler做數(shù)據(jù)處理。也就是說,一個(gè)what不僅僅對(duì)應(yīng)一個(gè)handler,而是對(duì)應(yīng)多個(gè)handler

2)監(jiān)聽者處理數(shù)據(jù)

MonitorThread.run調(diào)用了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.根據(jù)eventStr和iface過濾有效數(shù)據(jù)
        //2.關(guān)鍵點(diǎn)為sendMessage
    }
    
    private void sendMessage(String iface, Message message) {
        SparseArray<Set<Handler>> ifaceHandlers = mHandlerMap.get(iface);//從mHandlerMap中獲取iface數(shù)組
        if (iface != null && ifaceHandlers != null) {
            if (isMonitoring(iface)) {
                boolean firstHandler = true;
                Set<Handler> ifaceWhatHandlers = ifaceHandlers.get(message.what);//數(shù)組存在,則通過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);//設(shè)置目標(biāo)對(duì)象
            message.sendToTarget();//發(fā)送給目標(biāo)對(duì)象
        }
    }

總結(jié)

1.我們一般設(shè)置回調(diào)時(shí),就是調(diào)用監(jiān)聽者的回調(diào)方法,而這里的監(jiān)聽處理就顯著與眾不同
2.因?yàn)樗卣{(diào)給的是目標(biāo)對(duì)象的handler
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容