wifiTrackerlib源码解读

news/2024/11/7 10:34:31/

1. 监听wifi相关的Broadcast

1.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相关信息

  • 1.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

  • 1.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函数,

  • 1.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的回调。

  • 1.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

  • 1.6 BaseWifiTracker.java的功能

  • 1.6.1 BaseWifiTracker.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.

  • 1.6.2 BaseWifiTracker.java的监听wifi相关功能
监听wifi相关的BroadCast信号,然后收到了BroadCast之后进入实现的BroadcastReceiver,  这里会调用到handle....的回调方法,以handleNetworkStateChangedAction为例。
  • handleNetworkStateChangedAction
WifiPickerTracker继承了BaseWifiTracker,WifiPickerTracker.java实现了接口handleNetworkStateChangedAction,最后调用了updateWifiEntries()接口来更新扫描到的Wifi设备。
  •  1.6.3 wifi的连接状态、扫描结果,信号变化的信号监听

1.7.总结:

总的来说:0)createWifiPickerTracker创建WifiPickerTracker对象,传入lifeCycle变量。

1)BaseWifiTracker在根据传入的lifeCycle,在收到onStart事件后,开始监听wifi相关的信号。

2)然后调用继承BaseWifiTracker的子类WifiPickerTracker来更新wifi相关结果

3)WifiPickerTracker提供接口供app使用--比如fetchEntries(); 拿到扫描到的wifi

2.wifi的连接,断开,忽略操作:

 2.1 调用入口

调用的是WifiEntryListPreferenceController.java的createWifiEntryPreference方法

wifiEntry.connect(new WifiEntryConnectCallback(wifiEntry, /* editIfNoConfig= */ true));

查看wifiEntry.java的connect方法:

public void connect(@Nullable ConnectCallback callback) {
        // Do nothing.
    }

那么这个wifiEntry应该就是指的是继承wifiEntry的对象实现的connect方法。

2.2 查看connect方法的调用栈:

  • updateState: connect方法是在updateState()中调用的,是从fetchWifiEntries();中拿到的对象。
  • fetchWifiEntries: 调用的是 WifiEntry connectedWifiEntry=getCarWifiManager().getConnectedWifiEntry();
  • 即CarWifiManager.java的getConnectedWifiEntry方法中的mWifiTracker.getConnectedWifiEntry();
  • 即WifiPickerTracker.getConnectedWifiEntry方法。
  • 而getConnectedWifiEntry指定的对象是updateWifiEntries()中更新的mWifiEntries。

从而可以发现,mWifiEntries存入的对象是StandardWifiEntry,PasspointWifiEntry,OsuWifiEntry。。。本文以最常用的StandardWifiEntry为切入点。那么wifiEntry.connect应该是调用到StandardWifiEntry.connect方法,在StandardWifiEntry类中可以找打如下的方法。

2.3 StandardWifiEntry.java

  • 连接调用

mWifiManager.connect(mTargetWifiConfig.networkId, new ConnectActionListener()); 

ConnectActionListener是在WifiEntry.java中实现的,处理连接成功,失败的事件

  • 断开连接

mWifiManager.disconnect();

  • 忽略连接

mWifiManager.forget(mTargetWifiConfig.networkId, new ForgetActionListener());

ForgetActionListener是在WifiEntry.java中实现的,处理连接成功,失败的事件


http://www.ppmy.cn/news/1545033.html

相关文章

【系统集成项目管理工程师教程】第10章 启动过程组

启动过程组包含制定项目章程和识别干系人两个过程&#xff0c;是项目的起始阶段&#xff0c;旨在协调各方期望&#xff0c;明确项目范围、目标与干系人&#xff0c;确保项目符合组织战略&#xff0c;为项目成功奠定基础&#xff0c;在项目管理中起着至关重要的引领作用。 10.…

基于微信小程序的移动学习平台的设计与实现+ssm(lw+演示+源码+运行)

摘 要 由于APP软件在开发以及运营上面所需成本较高&#xff0c;而用户手机需要安装各种APP软件&#xff0c;因此占用用户过多的手机存储空间&#xff0c;导致用户手机运行缓慢&#xff0c;体验度比较差&#xff0c;进而导致用户会卸载非必要的APP&#xff0c;倒逼管理者必须改…

Go API 多种响应的规范化处理和简化策略

一个对外提供API接口的服务&#xff0c;在真正动工开发接口前一般需要先确定一下接口响应的通用格式&#xff0c;无论接口响应里返不返回业务数据&#xff0c;返回的数据是字符串、列表、对象还是其他类型都会遵照这个通用的响应格式。 既然一个项目接口的响应格式是确定的&…

在 MacOS 上跑 kaldi

categories: [asr] tags: C asr kaldi 在MacOS 下跑 kaldi brew install automake llvm cmake sox libtool subversion基本安装 Common build problems pyenv/pyenv Wiki; brew install pyenv pyenv install -v 2.7.18# Set the python version.pyenv global 2.7.18 # Expor…

【Vue 全家桶】7、Vue UI组件库(更新中)

目录 Element UI移动三级目录 Element UI 移动 三级目录

udp丢包问题

udp或者tcp丢包问题监测方式&#xff1a; netstat -su 问题分析&#xff1a; 1. 内存 2. cpu 3. 发送接收缓存 动画图解 socket 缓冲区的那些事儿-CSDN博客

51c自动驾驶~合集5

我自己的原文哦~ https://blog.51cto.com/whaosoft/11563178 #MapDistill 速度精度双起飞&#xff0c;让End2End更丝滑 在线高精&#xff08;HD&#xff09;地图构建是自动驾驶领域的一项重要且具有挑战性的任务。最近&#xff0c;人们对不依赖于激光雷达等其他传感器的基于…

Vue2中使用firefox的pdfjs进行文件文件流预览

文章目录 1.使用场景2. 使用方式1. npm 包下载,[点击查看](https://www.npmjs.com/package/pdfjs-dist)2. 官网下载1. 放到public文件夹下面2. 官网下载地址[点我,进入官网](https://github.com/mozilla/pdf.js/tags?afterv3.3.122) 3. 代码演示4. 图片预览5. 如果遇到跨域或者…