1. 前言:
- Android 4.4 原生Settings代碼路徑: android-4.4.4/packages/apps/Settings.
- 代碼架構(gòu): 相對簡單, 沒有按照MVC, 或者M(jìn)VP的形式來規(guī)劃源碼架構(gòu), 所以很多做系統(tǒng)開發(fā)的開發(fā)者很難聚焦來看源碼的實(shí)現(xiàn).
2. Android 4.4 WiFi 部分的源碼解析:
2.1 WIFI 模塊整體的功能結(jié)構(gòu):
- 開啟 WiFi
- 關(guān)閉 WiFi
- 獲取 WiFi 列表
- 持續(xù)掃描 WiFi ap.
- 連接網(wǎng)絡(luò)
- 忘記網(wǎng)絡(luò)
- 添加網(wǎng)絡(luò)
- 網(wǎng)絡(luò)高級設(shè)置等.
2.2 WiFi 整體功能示意圖:
2.3 WiFi 功能的主承載體:
- WifiSettings.java, 本質(zhì)是繼承自 PreferenceFragment , 其路徑: com.android.settings.wifi
- 對于安卓網(wǎng)絡(luò)廣播的處理, 也是在此類中, 在創(chuàng)建Fragment對象的時(shí)候, 進(jìn)行了一些列的初始化, 其中包含接收廣播的ACTION, 接收ACTION后對其處理的函數(shù)handleEvent(context, intent):
- Scanner類: 集成自Handler的一個(gè)Object類, 是WifiSettings的一個(gè)內(nèi)部類, 負(fù)責(zé)在WiFi狀態(tài)開啟時(shí), 調(diào)度自身進(jìn)行掃描WiFi的任務(wù)輪詢, 并且暴露出 resume(), forceScan(), pause() 的函數(shù).
- 其中:
- resume() 是發(fā)消息給自身, 來執(zhí)行掃描的操作.
- forceScan(), 強(qiáng)制掃描, 移除原有消息隊(duì)列中的任務(wù), 發(fā)送新的任務(wù), 強(qiáng)制重新掃描.
- pause(), 是移除自身掃描任務(wù)的消息, 退出掃描輪詢操作.
2.4 生命周期函數(shù)及部分回調(diào)函數(shù)的處理:
- onCreateView 中做了部分初始化. 如subMenu的一些處理, 添加網(wǎng)絡(luò), 高級設(shè)置等.
- onActivityCreate 中做了如下相關(guān)的參數(shù)初始化.
- a. 初始化WiFi管理類, WifiManager.
- b. 初始化連接, 保存, 忘記網(wǎng)絡(luò)的回調(diào)初始化. ActionListener.
- c. wifi 開關(guān), 及動態(tài)偵測WiFi狀態(tài)的輔助類的初始化.
- onResume 中, 注冊了WiFi狀態(tài)的監(jiān)聽廣播, 和WiFi列表及熱點(diǎn)變更,網(wǎng)絡(luò)狀態(tài)的廣播. 并更新當(dāng)前 ap.
-
onPause 中, 解除了onResume函數(shù)中注冊的相關(guān)廣播. 并且移除掉了掃描任務(wù). (可以理解為, 釋放資源, 避免內(nèi)存泄漏.)
-
onCreateOptionsMenu 中, 則初始化, 添加了一些高級設(shè)置, 輔助WiFi的操作控件. 如下:
- onOptionsMenuSelected 中, 針對上述添加的控件, 做了一些特定的響應(yīng), 根據(jù)其itemId 來區(qū)分, 當(dāng)前操作的是哪個(gè)具體的菜單.
- onCreateContextMenu 中, 針對當(dāng)前每一個(gè)WiFi列表中的, WiFi 網(wǎng)絡(luò), 添加了一些條目處理. 如果是未保存的網(wǎng)絡(luò), 則賦予其連接的動作. 如果是已保存網(wǎng)絡(luò), 則賦予其忘記網(wǎng)絡(luò), 修改網(wǎng)絡(luò)的動作.
- onOptionsItemSelected 中, 針對選項(xiàng)操作菜單中的各個(gè)條目進(jìn)行一些列的UI 或 WiFi 操作處理.
- onPreferenceTreeClick, 其實(shí)相當(dāng)于是ListView 的 onItemClickListener 的回調(diào)方法, 在Preference 列表中, 是對各條目點(diǎn)擊操作的回調(diào)函數(shù), 其中, 對于當(dāng)前網(wǎng)絡(luò)的連接的處理. 對于未保存, 無密碼的, 直接連接, 否則彈框讓用戶鍵入用戶密碼后, 進(jìn)行保存, 或連接.
2.5 關(guān)于 WIFI 刷新的那些事兒:
- 之前提到的最重要的, 關(guān)于網(wǎng)絡(luò)廣播的回調(diào)及監(jiān)聽, 在handleEvent中做了處理, 包括更新當(dāng)前WiFi列表, 刷新網(wǎng)絡(luò)數(shù)據(jù)結(jié)構(gòu). (AccessPoint) 等, 均是此處接收到原生廣播后, 進(jìn)行的統(tǒng)一處理.
- 關(guān)于刷新的那些事兒: 根據(jù)接收安卓系統(tǒng)廣播, 通過刷新數(shù)據(jù), 進(jìn)而開始刷新UI, 更新每個(gè) preference 條目的熱點(diǎn)數(shù)據(jù)結(jié)構(gòu)完成.
- 通過監(jiān)聽 WiFi 狀態(tài)變化, (相關(guān)的ACTION: WifiManager.WIFI_STATE_CHANGED_ACTION) 更新 optionsMenu, 其實(shí), 根據(jù)WiFi狀態(tài)改變, 決定是否掃描. 相關(guān)的調(diào)用比較簡單. 見圖:
- 通過監(jiān)聽底層掃描, 網(wǎng)絡(luò)配置變化, (相關(guān)的ACTION: WifiManager.SCAN_RESULTS_AVAILABLE_ACTION, WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION, WifiManager.LINK_CONFIGURATION_CHANGED_ACTION) 來更新 AccessPoint 數(shù)據(jù)結(jié)構(gòu), 進(jìn)而更新每個(gè) preference 持有的 accessPoint, 相當(dāng)于更新 ListView / RecyclerView 中itemView 的Tag. 相關(guān)的更新如下圖所示: (4.4 的做法, 是移除所有的 preference 容器中的所有 UI, 然后重新初始化, 沒做緩存).
- 通過監(jiān)聽WiFi請求狀態(tài)的變化, (相關(guān)的ACTION: WifiManager.SUPPLICANT_STATE_CHANGED_ACTION) 來更新網(wǎng)絡(luò)連接狀態(tài), 更新每個(gè)條目中的 DetailedState 來刷新每個(gè)條目持有的accessPoint.
- 通過網(wǎng)絡(luò)變化, (相關(guān)的ACTION: WifiManager.NETWORK_STATE_CHANGED_ACTION) 刷新熱點(diǎn), 更新連接狀態(tài). 相關(guān)代碼如下:
- 通過監(jiān)聽網(wǎng)絡(luò)信號變化, (相關(guān)的ACTION: WifiManager.RSSI_CHANGED_ACTION) 刷新條目狀態(tài).
3. 小結(jié):
- 如上, 針對原生 Android Settings源代碼, 結(jié)合自身閱讀源碼的一些經(jīng)驗(yàn)和見解, 形成了如上文檔作為歸結(jié), 其一, 對源碼的理解會加深印象, 后期有疑問可快速查詢定位, 其二, 希望能對剛踏入系統(tǒng)開發(fā)者兄弟做一些入門指導(dǎo). 如上, 感謝~~~
- 如文章中有不合適之處, 或有疑問, 請簡信, 或郵箱告知. 亦可下方評論區(qū)留言.
- qq 郵箱: 1281641968@qq.com