wifiTrackerlib之监听wifi相关的Broadcast
1.根据布局找到wifi显示用到的方法
- 首先研究原生carSetting的代码布局---找到wifi_list_fragment.xml,可以知道这里是wifi显示界面的xml
- 然后是找到wifi对应的布局部分:
<com.android.car.ui.preference.CarUiPreferenceandroid:key="@string/pk_wifi_status"settings:controller="com.android.car.settings.wifi.WifiStatusPreferenceController"settings:showChevron="false"/><com.android.car.settings.common.LogicalPreferenceGroupandroid:key="@string/pk_wifi_list"settings:controller="com.android.car.settings.wifi.WifiEntryListPreferenceController"/><com.android.car.ui.preference.CarUiPreferenceandroid:fragment="com.android.car.settings.wifi.AddWifiFragment"android:icon="@drawable/ic_add"android:key="@string/pk_add_wifi"android:title="@string/wifi_setup_add_network"settings:controller="com.android.car.settings.wifi.AddWifiPreferenceController"settings:showChevron="false"/>
不需要明白这个Preference是干嘛的,只需要了解:
WifiStatusPreferenceController用来拿wifi状态
WifiEntryListPreferenceController用来拿wifi相关信息
AddWifiPreferenceController用来添加更多的wifi相关信息
-
2.WifiEntryListPreferenceController
在WifiEntryListPreferenceController.java中 updateState函数拿到了wifi项,获取了已连接和未连接的wifi项。
@Overrideprotected void updateState(PreferenceGroup preferenceGroup) {if (getCarWifiManager() == null) {return;}mWifiEntries = fetchWifiEntries(); // 获取所有的wifi项LOG.d("showing wifiEntries: " + mWifiEntries.size());preferenceGroup.setVisible(!mWifiEntries.isEmpty());preferenceGroup.removeAll();WifiEntry connectedWifiEntry = getCarWifiManager().getConnectedWifiEntry(); // 获取已连接的wifi项for (WifiEntry wifiEntry : mWifiEntries) {if (wifiEntry.equals(connectedWifiEntry)) {preferenceGroup.addPreference(createWifiEntryPreference(wifiEntry, /* connected= */ true));} else {preferenceGroup.addPreference(createWifiEntryPreference(wifiEntry, /* connected= */ false));}}}
其中关键的就是getCarWifiManager();
于是研究CarWifiManger的构造函数,即WifiBasePreferenceController.java其中的new CarWifiManager
-
3.CarWifiManger的构造函数
收
public CarWifiManager(Context context, Lifecycle lifecycle) {mContext = context;mLifecycle = lifecycle;mLifecycle.addObserver(this);mWifiManager = mContext.getSystemService(WifiManager.class);mWorkerThread = new HandlerThread(TAG+ "{" + Integer.toHexString(System.identityHashCode(this)) + "}",android.os.Process.THREAD_PRIORITY_BACKGROUND);mWorkerThread.start();mWifiTracker = WifiUtil.createWifiPickerTracker(lifecycle, context,new Handler(Looper.getMainLooper()), mWorkerThread.getThreadHandler(),/* listener= */ this);}
其中的关键就是WifiUtil的createWifiPickerTracker函数,
-
4.createWifiPickerTracker
在WifiUtil.java中的createWifiPickerTracker传入了几个参数:
mWifiTracker = WifiUtil.createWifiPickerTracker(lifecycle, context,new Handler(Looper.getMainLooper()), mWorkerThread.getThreadHandler(),/* listener= */ this);
1)mainHandler--即new Handler(Looper.getMainLooper()); 这个是主线程的UI handler
2)而mWorkHandler--用来处理非UI事件
3) listener则是调用WifiPickerTracker.WifiPickerTrackerCallback这个回调的地方,可以看到CarWifiManager.java中的onWifiStateChanged是实现WifiPickerTrackerCallback的回调。
-
5.wifiPickerTracker的构造
public static WifiPickerTracker createWifiPickerTracker(Lifecycle lifecycle, Context context,Handler mainHandler, Handler workerHandler,long maxScanAgeMillis, long scanIntervalMillis,WifiPickerTracker.WifiPickerTrackerCallback listener) {return new WifiPickerTracker(lifecycle, context,context.getSystemService(WifiManager.class),context.getSystemService(ConnectivityManager.class),context.getSystemService(NetworkScoreManager.class),mainHandler, workerHandler, ELAPSED_REALTIME_CLOCK,maxScanAgeMillis, scanIntervalMillis,listener);}
WifiPickerTracker.java 在 frameworks/opt/net/wifi/libs/WifiTrackerlib/src目录下。
而 class WifiPickerTracker extends BaseWifiTracker, 翻看BaseWifiTracker
-
6.BaseWifiTracker.java的功能
-
6.1BaseWifiTracker.java的onStart和onStop
以下是个人觉得比较重要的点:
1) onStart 和 onStop, 其中onStart在收到 Lifecycle.Event.ON_STAR会调用。而onStop收到Lifecycle.Event.ON_STOP会调用。
- 那么这个lifecycle是指的什么呢? 在BaseWifiTracker的构造函数中:调用了lifecycle.addObserver(this);
- 看下调用栈, 从CarWifiManager的构造函数---->createWifiPickerTracker---->wifiPickerTracker的构造---> BaseWifiTracker的构造。
lifeCycle是从CarWifiManager的构造函数传过来的、而CarWifiManger的构造函数也调用了mLifecycle.addObserver(this); 这个界面也实现了onStart回调来监听Lifecycle.Event.ON_START。
- 那么onStart则是先调用到CarWifiManager类,在调用到BaseWifiTracker类。
2)BaseWifiTracker的onStart监听了wifi相关的BroadCast, 而在onStop取消了监听wifi相关的BroadCast
(所以当出现不能收到wifi相关的BroadCast后,考虑是不是调用到了onStop, 之后未调用到onStart. )
-
6.2 BaseWifiTracker.java的监听wifi相关功能
监听wifi相关的BroadCast信号,然后收到了BroadCast之后进入实现的BroadcastReceiver, 这里会调用到handle....的回调方法,以handleNetworkStateChangedAction为例。
- handleNetworkStateChangedAction
WifiPickerTracker继承了BaseWifiTracker,WifiPickerTracker.java实现了接口handleNetworkStateChangedAction,最后调用了updateWifiEntries()接口来更新扫描到的Wifi设备。
-
6.3 wifi的连接状态、扫描结果,信号变化的信号监听
7.总结:
总的来说:0)createWifiPickerTracker创建WifiPickerTracker对象,传入lifeCycle变量。
1)BaseWifiTracker在根据传入的lifeCycle,在收到onStart事件后,开始监听wifi相关的信号。
2)然后调用继承BaseWifiTracker的子类WifiPickerTracker来更新wifi相关结果
3)WifiPickerTracker提供接口供app使用--比如fetchEntries(); 拿到扫描到的wifi