引言:这篇文章以WiFi举例,介绍了Android系统网络架构。其内容包含:网络链路的连接和注册、网络有效性检测和网络优选、Android系统网络防火墙和几种场景下的网络策略等,文章的最后也列举了几种常见的无法上网原因供大家参考。
一. 基本结构
1.1 类图
1.2 WifiService
WifiManager中公开API的具体实现,提供了WiFi打开与关闭、配置和扫描、连接和断开等方法,其中也包含了对调用者的权限检查,如开关WiFi需要"Manifest.permission.CHANGE_WIFI_STATE"
权限等。外部调用方式为:
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
1.3 WifiStateMachine
状态机: 状态机是一种用于表示有限个状态以及在这些状态之间转移和动作行为的数学模型。状态机描述了对象在它生命周期内所经历的状态序列,以及在不同状态下如何响应外部事件。使用状态机可以省去代码中一堆的"if-else"判断,这样不仅易于管理,同时也使代码结构更加清晰,易于阅读。
WifiStateMachine是一个状态机,用于管理WiFi驱动加载、扫描、连接、获取IP、漫游等各个状态。基本的状态如图:("→"的起始端为父状态,终端为子状态;外部消息可以在子→父状态中流动,子状态不处理的消息交由父状态处理)
各个状态的描述:
State | Description |
---|---|
DefaultState | 初始状态,WiFi 开关没有打开,驱动没有加载。当处于其他状态时,消息由子状态上行可用于日志打印。 |
ConnectModeState | ConnectModeStateWiFi开关已经打开,驱动已经加载,native中wpa_supplicant已经启动。此时可以进行扫描和连接的操作。 进入该状态时发送 “android.net.wifi.WIFI_STATE_CHANGED” 广播。 |
L2ConnectedState | L2是"Level 2"的意思,代表OSI网络模型中的2层即数据链路层。这个状态代表数据链路已经建立完成。 进入该状态时发送"android.net.wifi.STATE_CHANGE"广播,连接状态是CONNECTING。 |
ObtainingIpState | DHCP获取IP过程时的状态。 |
ConnectedState | 已连接状态,当链路建立完成且DHCP配置IP完成后会进入该状态。 进入该状态时发送"android.net.wifi.STATE_CHANGE"广播,连接状态是CONNECTED。 |
RoamingState | 漫游状态。如果附近的两个热点名字(ssid)相同,且网络质量达到一定差异化时,系统就会进入漫游状态,连接到另一个热点。 |
DisconnectingState | 断开中状态。从断开发起到断开成功,处于该状态。 进入该状态会发送 “android.net.wifi.STATE_CHANGE” 广播,连接状态是DISCONNECTING。 |
DisconnectedState | 已断开状态。进入该状态时会发送"android.net.wifi.STATE_CHANGE" 广播,连接状态是DISCONNECTED。 |
adb连接状态下可以使用 “adb shell dumpsys wifi” 来查看连接WiFi的信息和连接的详细过程,如:
上一次扫描结果:
Latest scan results:
BSSID Frequency RSSI Age SSID Flags
80:8d:b7:62:da:12 5765 -52 1.330+ Bytedance Inc [WPA2-EAP-CCMP][ESS]
80:8d:b7:62:da:15 5765 -53 94.471 Bytedance AD [WPA2-EAP-CCMP][ESS]
80:8d:b7:62:da:14 5765 -53 94.471 jiyunhudong [WPA2-EAP-CCMP][ESS]
80:8d:b7:62:da:13 5765 -53 94.471 Bytedance 2.4G [WPA2-EAP-CCMP][ESS]
80:8d:b7:63:12:d4 5805 -71 94.471 jiyunhudong [WPA2-EAP-CCMP][ESS]
80:8d:b7:63:12:d5 5805 -71 94.469 Bytedance AD [WPA2-EAP-CCMP][ESS]
80:8d:b7:63:12:d2 5805 -71 94.469+ Bytedance Inc [WPA2-EAP-CCMP][ESS]
80:8d:b7:63:12:d3 5805 -71 94.469 Bytedance 2.4G [WPA2-EAP-CCMP][ESS]
80:8d:b7:62:da:02 2412 -54 94.469 Bytedance 2.4G [WPA2-EAP-CCMP][ESS]
80:8d:b7:63:43:d2 5260 -81 94.469+ Bytedance Inc [WPA2-EAP-CCMP][ESS]
80:8d:b7:63:43:d3 5260 -81 94.468 Bytedance 2.4G [WPA2-EAP-CCMP][ESS]
80:8d:b7:63:43:d0 5260 -81 94.468 [WPA2-PSK-CCMP][ESS]
80:8d:b7:63:43:d4 5260 -81 94.468 jiyunhudong [WPA2-EAP-CCMP][ESS]
80:8d:b7:63:43:d5 5260 -81 94.468 Bytedance AD [WPA2-EAP-CCMP][ESS]
80:8d:b7:62:df:73 5300 -87 94.468 Bytedance 2.4G [WPA2-EAP-CCMP][ESS]
80:8d:b7:60:26:50 5260 -87 94.468 [WPA2-PSK-CCMP][ESS]
80:8d:b7:60:26:52 5260 -86 94.468+ Bytedance Inc [WPA2-EAP-CCMP][ESS]
80:8d:b7:60:26:54 5260 -86 94.467 jiyunhudong [WPA2-EAP-CCMP][ESS]
80:8d:b7:60:26:53 5260 -86 94.467 Bytedance 2.4G [WPA2-EAP-CCMP][ESS]
80:8d:b7:60:26:55 5260 -86 94.467 Bytedance AD [WPA2-EAP-CCMP][ESS]
80:8d:b7:62:da:11 5765 -53 94.467 Bytedance Guest [ESS]
80:8d:b7:63:12:d1 5805 -71 94.467 Bytedance Guest [ESS]
80:8d:b7:62:da:01 2412 -53 94.467 Bytedance Guest [ESS]
80:8d:b7:63:43:d1 5260 -80 94.467 Bytedance Guest [ESS]
80:8d:b7:63:05:22 2437 -68 94.467 Bytedance Guest [ESS]
80:8d:b7:60:26:51 5260 -87 94.466 Bytedance Guest [ESS]
80:8d:b7:63:38:f3 5200 -73 94.466 Bytedance 2.4G [WPA2-EAP-CCMP][ESS]
一次L2连接成功的过程:
rec[34]: time=04-08 21:36:05.811 processed=ConnectModeState org=DisconnectedState dest=<null> what=147462(0x24006) !SUPPLICANT_STATE_CHANGE_EVENT
rt=34877/34863 29 0 SSID: Bytedance Inc BSSID: 00:00:00:00:00:00 nid: 1 state: ASSOCIATING
rec[35]: time=04-08 21:36:05.910 processed=ConnectModeState org=DisconnectedState dest=<null> what=147462(0x24006) !SUPPLICANT_STATE_CHANGE_EVENT
rt=34976/34962 30 0 SSID: Bytedance Inc BSSID: 00:00:00:00:00:00 nid: 1 state: ASSOCIATED
rec[38]: time=04-08 21:36:06.055 processed=ConnectModeState org=DisconnectedState dest=<null> what=147462(0x24006) !SUPPLICANT_STATE_CHANGE_EVENT
rt=35121/35108 48 0 SSID: Bytedance Inc BSSID: 80:8d:b7:62:da:12 nid: 1 state: FOUR_WAY_HANDSHAKE
rec[39]: time=04-08 21:36:06.062 processed=ConnectModeState org=DisconnectedState dest=<null