Android WIFI 詳解
該類成員函數(shù)的也是通過調用mWifimanager的接口來實現(xiàn)的。
3) WifiManager:
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
兩個重要的數(shù)據(jù)成員:
//WifiService
IWifiManager mService;
HandlermHandler;
IWifiManager mService和HandlermHandler,這個類擁有了一個WifiService實例,就可以通過它進行一系列的調 用;WifiManager中定義了的wifi和ap的狀態(tài),這些狀態(tài)會在其他很多類中有使用;然后定義了大量的函數(shù),這些函數(shù)幾乎都是對 WifiService接口函數(shù)的封裝,直接調用WifiService的函數(shù)。
該類的構造函數(shù)很簡單:
public WifiManager(IWifiManager service,Handler handler) {
mService = service;
mHandler = handler;
}
該 類中還定義了一個WifiLock類,這個類用來保證在有應用程序使用Wifi無線電傳輸數(shù)據(jù)時,wifiradio可用,即當一個應用程序使用wifi 的radio進行無線電數(shù)據(jù)傳輸時,就要先獲得這個鎖,如果該鎖已被其他程序占有,就要等到該鎖被釋放后才能獲得,只用當所有持有該鎖的程序都釋放該鎖 后,才能關閉radio功能。
4)WifiService:
frameworks/base/services/java/com/android/server/WifiService.java
private final WifiStateTrackermWifiStateTracker;
private Context mContext;
private WifiWatchdogServicemWifiWatchdogService = null;
private final WifiHandler mWifiHandler;
這是WifiService中的幾個重要的數(shù)據(jù)成員。
在 接下來的構造函數(shù)中初始化了mWifiStateTracker,mContext,然后動態(tài)生成mWifiThread子線程并啟動,在主線程里用 mWifiThread調用getLooper()函數(shù)獲得線程的looper,來初始化創(chuàng)建一個mWifiHandler對象,這個 WifiHandler在WifiService類的后面有定義,并重載了Handler類的handlermessage()函數(shù),這樣消息就可以在主 線程里被處理了,這是android的handlerthread消息處理機制,可參考相關資料,這里不予詳述。在構造函數(shù)的最后,注冊了兩個廣播接收 器,分別用來ACTION_AIRPLANE_MODE_CHANGED和ACTION_TETHER_STATE_CHANGED這兩個動作,這里是 android的intent消息通知機制,請參考相關資料,代碼如下:
mContext = context;
mWifiStateTracker = tracker;
mWifiStateTracker.enableRssiPolling(true);
……
HandlerThread wifiThread = newHandlerThread(WifiService);
wifiThread.start();
mWifiHandler = newWifiHandler(wifiThread.getLooper());
……
隨 后定義了一系列的函數(shù),其中有服務器要發(fā)送的命令的系列函數(shù),它通過mWifiStateTracker成員類調用自己的的發(fā)送命令的接口(其實就是對本 地接口的一個封裝),最后通過適配層發(fā)送命令給wpa_supplicant,而事件處理只到WifiStateTracker層被處理。
要 注意的是,在WifiService中,定義了一些函數(shù)來創(chuàng)建消息,并通過mWifiHandler將消息發(fā)送到消息隊列上,然后在 mHandlerThread線程體run()分發(fā)處理消息,在主線程中被mWifiHandler的handlerMessage()函數(shù)處理,最后 調用mWifiStateTracker的對應函數(shù)來實現(xiàn)的。這里我也不明白為什么WifiService不直接調用mWifiStateTracker 對應的函數(shù),還要通過消息處理機制,繞了一圈在調用,當然Google這么做肯定是有它道理的,忘高手指點。
5) WifiStateTracker類:
frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java
NetworkStateTracker繼承了handler類,而WifiStateTracker繼承了NetworkStateTracker類,就是說WifiStateTracker間接繼承了handler類,屬于一個事件處理類。
WifiStateTracker類首先定義了事件日志和事件碼(這里包含了所有可能的事件類型),還定義了如下的重要成員數(shù)據(jù):
//幾個重要的數(shù)據(jù)成員
private WifiMonitor mWifiMonitor; //被啟動用來監(jiān)聽supplicant傳來的消息
private WifiInfo mWifiInfo;
private WifiManager mWM; //服務代理
private DhcpHandler mDhcpTarget; //IP地址獲取線程
private DhcpInfo mDhcpInfo; //Dhcp的相關信息都在這里
類的構造函數(shù)中,初始化了系列成員變量,包括生成了WifiMonitor的實例,在構造函數(shù)中,因為WifiStateTracker是一個handler間接子類,所以他會自動調用handler的無參構造函數(shù),獲得looper和Queue消息隊列。
然后定義了一些設置supplicant和更新網(wǎng)絡信息的輔助函數(shù)。
startEventLoop()函數(shù)很重要,用來啟動WifiMonitor線程,進入消息循環(huán)檢測。接著定義了系列通知函數(shù),被 WifiMonitor調用來向WifiStateTracker傳遞從wpa_supplicant接收到的消息,他會調用消息發(fā)送函數(shù)到消息隊列,并 被WifiStateTracker的handlermessage()函數(shù)處理。這個handlermessage()函數(shù)就是在隨后被定義的,它主要 是調用相應的輔助函數(shù)完成動作,并可能會將消息封裝后,通過intent機制發(fā)送出去,被上層的UI活動接收處理。
這 里也定義了很多的WfiNative接口函數(shù),這是JNI的本地接口;類DhcpHandler extends Handler{}也是在該類中定義的,它也是一個handler的子類,用來處理DHCP相關的消息EVENT_DHCP_START,可以想到它和 WifiStateTracker不是共用一個looper。
注意:handleMessage是在該文件中定義的,用來處理經(jīng)WifiMonitor轉換過的消息。
6) WifiMonitor
frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java
聲明了一個重要的成員變量:mWifiStateTracker,并在構造函數(shù)中由參數(shù)提供初始化,還定義了一系列的可能從wpa_supplicant層接收的事件類型及其名字,這些是消息處理機制的基礎。
startMonitoring()函數(shù),這是一個線程啟動的封裝函數(shù),WifiStateTracker就是通過這個函數(shù)啟動的WifiThread。
這 個重要的類classMonitorThreadextends Thread{};它是一個監(jiān)控進程類,里面有一系列的事件處理函數(shù)和一個重要的Run()函數(shù),run函數(shù)主要流 程:connectToSupplicant()連接精靈進程wpa_supplicant,這里有一個 mWifiStateTracker.notifySupplicantXXX()的調用,通知上層是否連接成功,然后就是一個輪詢過程,其中調用了 WifiNative.waitForEvent()本地輪詢函數(shù)接口,并從返回的事件字符串類型中提取事件的名稱,最后通過事件的名稱調用相應的事件處 理函數(shù),并將事件轉換成mWifiStateTracker能識別的類型上報。
評論