【安卓Framework学习】Wifi框架学习之开启与关闭流程
【安卓Framework学习】Wifi框架学习之wifi状态机
【安卓Framework学习】Wifi框架学习之连接与断开流程
【安卓Framework学习】Wifi框架学习之扫描模式及扫描流程
【安卓Framework学习】Wifi框架学习之热点评分机制
【安卓Framework学习】安卓连接管理(ConnectivityService)之wifi连接及注册.
前段时间做了一个wifi相关的需求,但是看了安卓wifi的标准api之后发现不够用,仍然会出现许多问题,比如wifi连接会有不稳定的时候,有时候能连接上有时候无法连接,但是却不知道是什么原因。为此萌发了去翻看wifi框架的源码进行学习。本文主要是针对wifi框架中的一些核心类,根据自己看源码的注释进行理解学习,可能理解得不那么精确,但掌握大致的意思。文中所有涉及到的源码均来源于Android11.
此类是暴露给应用层开发者使用的一个管理类,我认为是一个代理类,其主要作用有:
WifiConfiguration
对象中。ACTION_WIFI_SCAN_AVAILABILITY_CHANGED
表示当前的wifi扫描是否有效,通过获取EXTRA_SCAN_AVAILABLE来判定本次扫描是否可以获得扫描结果。SCAN_RESULTS_AVAILABLE_ACTION
表示扫描已经完成,并且可以获取扫描结果,通过getScanResults()
方法获取WIFI_STATE_CHANGED_ACTION
表示wifi的开启和关闭状态,一般会有已开启、正在开启、已关闭、正在关闭和未知这五个状态,通过EXTRA_WIFI_STATE
来获取当前的状态值。NETWORK_STATE_CHANGED_ACTION
表示wifi连接过程中的网络状态变化,可以通过获取EXTRA_NETWORK_INFO
得到一个NetworkInfo
对象获得详细的网络连接的状态信息。CONFIGURED_NETWORKS_CHANGED_ACTION
表示已经存在系统中配置好的WifiConfiguration
对象发生了变化和更新,获取EXTRA_WIFI_CONFIGURATION
得到WifiConfiguration
,但是在Android11之后就拿不到这个对象了。RSSI_CHANGED_ACTION
表示wifi的信号强度有变化,获取EXTRA_NEW_RSSI
得到新的信号强度。此类我认为是一个功能型类,继承了SystemService
,主要是方便SystemServer
统一启动其中的生命周期回调函数。在WifiService
中实例化了真正的IWifiManager
实现类的服务端WifiServiceImpl
,服务端中实现了主要的wifi框架功能和流程。
以下为WifiService
的构造函数,其中实例化了WifiServiceImpl
和WifiInjector
.
public WifiService(Context contextBase) {
super(contextBase);
mWifiContext = new WifiContext(contextBase);
WifiInjector injector = new WifiInjector(mWifiContext);
WifiAsyncChannel channel = new WifiAsyncChannel(TAG);
mImpl = new WifiServiceImpl(mWifiContext, injector, channel);
}
这个类是wifi框架中IWifiManager
接口的实现类了,实现了安卓Framework中的wifi相关服务的核心函数,通过Binder跨进程通信,由WifiManager
拿到其Binder对象调用相对应的api.
此类在WifiService
的构造函数中就实例化出一个对象,足以见得其与WifiServiceImpl
是具有同等地位和作用的。根据官方的注释解释,WifiInjector
是一个wifi相关类的依赖注入器,通过它可以获得各种wifi类的实例并且能够模拟注入。我推测其实官方为了方便测试wifi框架,然后用它来作为所有其他wifi相关类的一个入口,只要mock了它,就可以获得其他所有类,从而方便测试。
在Android9.0的版本时,还不存在这个类,其实本类就是之前的wifi状态机WifiStateMachine
,ClientModeImpl
是由WifiInjector
在初始化的时候实例化出来的对象,在WifiServiceImpl
对象初始化的时候会去获得其对象。由于wifi框架中存在许多状态,大量运用到了状态模式来做开发,这个类主要处理wifi连接和断开的过程状态,所以一些连接、断开等业务实现是服务端WifiServiceImpl
通过给ClientModeImpl
发送消息然后交给它来实现具体的业务和切换具体的状态,每个状态在对同一个消息会有不同的处理。和之前WifiStateMachine
不同,ClientModeImpl
在Android11中将其他的状态移到别的类重了,目前只包含了8个状态,分别为DefaultState
、ConnectModeState
、L2ConnectedState
、DisconnectedState
、DisconnectingState
、RoamingState
、ObtainingIpState
、ConnectedState
,如果对状态模式不了解的可以另行学习。
这个类就顾名思义了,和底层(对接的其实是HAL层Framework)真正去操作wifi模块的守护进程直接发送请求,请求wifi模块扫描、pno扫描、连接、断开以及这些操作之后的状态返回通过回调来通知上层Framework是否成功或者是其他结果。
此类管理来自外部应用程序的所有扫描请求,在WifiServiceImpl
和WifiScanningServiceImpl
之间作为一个代理类。其主要职责有:
WifiServiceImpl
和WifiScanningServiceImpl
之间getScanResults()
可以获取扫描结果SCAN_RESULTS_AVAILABLE_ACTION
广播和WifiManager
一样在同一个位置被初始化,作为暴露给上层的一个wifi扫描的管理类,但是平时开发并不能够直接获得。其封装了一些api,然后通过异步通信AsyncChannel
与WifiScanningServiceImpl
之间进行消息发送和接收,实现响应的扫描功能和结果返回。
此类与WifiService
一样,继承了SystemService
,主要是方便SystemServer
统一启动其中的生命周期回调函数。在WifiScanningService
中实例化了真正的IWifiScanner
实现类的服务端WifiScanningServiceImpl
,服务端中实现了主要的wifi框架中扫描功能。
以下为WifiScanningService
的构造函数,其中实例化了WifiScanningServiceImpl
.
public WifiScanningService(Context contextBase) {
super(new WifiContext(contextBase));
Log.i(TAG, "Creating " + Context.WIFI_SCANNING_SERVICE);
mHandlerThread = new HandlerThread("WifiScanningService");
mHandlerThread.start();
mImpl = new WifiScanningServiceImpl(getContext(), mHandlerThread.getLooper(),
WifiScannerImpl.DEFAULT_FACTORY,
getContext().getSystemService(BatteryStatsManager.class),
WifiInjector.getInstance());
}
这个类与WifiServiceImpl
一样,是对IWifiScanner
的实现,实现了wifi扫描服务主要的功能,主要是体现了三种扫描方式单次扫描、后台扫描、PNO扫描,这三种扫描方式对应的策略和场景不同不在这做详细描述,但是同时在这个类里面对应三种不同的状态机WifiSingleScanStateMachine
、WifiBackgroundScanStateMachine
、WifiPnoScanStateMachine
.
这个类用来注册wifi相关服务,可以在这里看到WifiManager
和WifiScanner
都是在这里被实例化,并且获得相对应的远端服务的Binder对象的。
public static void registerServiceWrappers() {
SystemServiceRegistry.registerContextAwareService(
Context.WIFI_SERVICE,
WifiManager.class,
(context, serviceBinder) -> {
IWifiManager service = IWifiManager.Stub.asInterface(serviceBinder);
return new WifiManager(context, service, getInstanceLooper());
}
);
...//此处省略部分注册
SystemServiceRegistry.registerContextAwareService(
Context.WIFI_SCANNING_SERVICE,
WifiScanner.class,
(context, serviceBinder) -> {
IWifiScanner service = IWifiScanner.Stub.asInterface(serviceBinder);
return new WifiScanner(context, service, getInstanceLooper());
}
);
...//此处省略部分注册
}
WifiMonitor
就是用来监听wpa_supplicant
和wificond
上报上来的事件,并且在java层Framework中将这些事件广播出去。wifi框架中的其他类例如ClientModeImpl
会将自己的Handler
注册到WifiMonitor
中,WifiMonitor
在接收到wpa_supplicant
和wificond
上报上来的事件然后给监听了对应消息的Handler
发送消息,拥有Handler
对象的类根据实际业务再做响应的处理。
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);
}
这个类就是用来管理所有的wifi连接的扫描活动,当屏幕开启或关闭、wifi连接或断开或者有扫描需求时,都会启动一次扫描,并将扫描结果传递给wifi框架选择并评分,然后让wifi框架选择出扫描结果中最优的热点最为推荐热点。
总结起来,其实wifi框架主要是类比较繁多,但其实结构较为简单,主要是围绕wifi连接服务类和wifi扫描服务类