android网络的评分机制、连接国内ap wifi不回连问题

本文探讨了Android网络评分机制,其中WiFi、Ethernet和Mobile network的初始分值分别为60、70和50。WiFi的分数受到信号状态、数据速率等因素影响。在无法连接到Internet时,系统会进行周期性检测。在中国大陆,由于无法连接Google服务器,WiFi可能显示为未连接,并不会自动重连。解决方案包括修改系统代码和调整网络检测地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:
本文介绍了android下网络的评分机制,同时分析wifi连接国内ap时,重新打开wifi后,wifi不回连ap的问题,并提供解决方法。

android下可以有多种网络存在,如:wifi、mobile network、ethernet、bt-pan。而对于上层应用来说,只会看到一个连通的网络,在多个网络同时存在的情况下,android就需要一套评分机制来选择一个当前使用的网络,当那个网络的分值高时,就优先使用那个网络。
Android下各种网络的分值在NetworkAgentInfo.java中管理,保存在currentScore中,各种网络初始化时会设置自己的分值。

Wifi初始分值为60(WifiStateMachine.java);
Ethernet初始分值为70(EthernetNetworkFactory.java);
Mobile network初始分值为50(DataConnection.java);
bt-pan初始分值为69(BluetoothTetheringNetworkFactory.java):
bt-pan的分值比wifi还高,这比较奇怪,已知的bt-pan网速都比较慢,google出于什么原因设计成这样?就不清楚了。

在实际运行中,还会根据网络的实时状态调整分值。

ethernet根据网卡的up和down状态,把分值设置为70(NETWORK_SCORE)或0。

(EthernetNetworkFactory.java)
mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0); 

而wifi的分值还跟信号状态、当前数据速率等一系列因素有关:
Wifi的分值计算在WifiStateMachine.java的calculateWifiScore函数中进行,初始计算的基础分值为:int score = 56;根据wifi网络的状态,进行小的加减,最后,如果分值大于60(NetworkAgent.WIFI_BASE_SCORE),就把分值设置为60。
上面设置的分值计算,只考虑网络是否连接好,至于连接的网络是否能连接上internet,还没加入考虑。如wifi已经连接上ap,而该ap是否能连接上internet,就没在这里考虑。
上面设置的网络分值,是最终保存在NetworkAgentInfo类中的分值,而在获取网络分值时,还会根据网络是否连接上internet,是否用户指定使用的网络,返回经过计算后的分值。

NetworkAgentInfo.java
    private int getCurrentScore(boolean pretendValidated) {
        // TODO: We may want to refactor this into a NetworkScore class that takes a base score from
        // the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the
        // score.  The NetworkScore class would provide a nice place to centralize score constants
        // so they are not scattered about the transports.
        int score = currentScore;
        if (!everValidated && !pretendValidated) score -= UNVALIDATED_SCORE_PENALTY;
        if (score < 0) score = 0;
        if (networkMisc.explicitlySelected) score = EXPLICITLY_SELECTED_NETWORK_SCORE;
        return score;
    }
如果需要根据网络是否连通internet,就进行if (!everValidated && !pretendValidated) score -= UNVALIDATED_SCORE_PENALTY(40);处理,当网络与internet不通时,分值减去40。如果是用户指定使用的网络,直接返回分值if (networkMisc.explicitlySelected) score = EXPLICITLY_SELECTED_NETWORK_SCORE;(100)。
pretendValidated参数确定是否认为当前网络就是与internet连通的。everValidated表示当前网络与internet是否连通的标志。networkMisc.explicitlySelected为用户是否指定使用当前网络的标志,在用户手动连接ap的时候,该标志就会被设置,所以这时候的分值比ethernet还高,就会优先选择wifi作为首选网络。但在开关wifi后,自动连接上ap时,该标志就不会设置。

最后,分析一下everValidated标志是由哪里设置的,这里以wifi作为例子分析。
在连接wifi的过程中,当WifiStateMachine进入L2ConnectedState时,就会创建:
    mNetworkAgent = new WifiNetworkAgent(getHandler().getLooper(), mContext,
                    "WifiNetworkAgent", mNetworkInfo, mNetworkCapabilitiesFilter,
                    mLinkProperties, 60);
在WifiNetworkAgent初始化时,把everValidated设置为false,而当网络断开连接时,就会注销WifiNetworkAgent:
        if (mNetworkAgent != null) {
            mNetworkAgent.sendNetworkInfo(mNetworkInfo);
            mNetworkAgent = null;
        }
所以在每次连接网络后,都会重新设置everValidated,断开网络时就会清除。
创建WifiNetworkAgent时,在WifiNetworkAgent内创建了NetworkMonitor, NetworkMonitor就是一个检测网络的状态机,状态机包含下面状态,初始状态为mDefaultState,检测网络是否与internet连通就是在该状态机中实现。
        addState(mDefaultState);
        addState(mOfflineState, mDefaultState);
        addState(mValidatedState, mDefaultState);
        addState(mMaybeNotifyState, mDefaultState);
            addState(mEvaluatingState, mMaybeNotifyState);
            addState(mCaptivePortalState, mMaybeNotifyState);
        addState(mLingeringState, mDefaultState);
        setInitialState(mDefaultState);
当网络与internet连通时,NetworkMonitor所走的状态机如下图:

这里写图片描述

当进入mValidatedState时,就会给connectivity发送消息:
   mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,

NETWORK_TEST_RESULT_VALID, mNetwork3gTestResultIsFake,
mNetworkAgentInfo));
connectivity对NETWORK_TEST_RESULT_VALID消息进行处理时,就会设置everValidated为true。

检测网络是否连通的代码如下:
android\frameworks\base\services\core\java\com\android\server\connectivity\ NetworkMonitor.java
            public boolean processMessage(Message message) {
            if (DBG) log(getName() + message.toString());
            
<think>好的,我现在需要处理用户提供的这个日志条目,并解释其中与漫游相关的部分。首先,我要仔细分析日志中的各个字段,理解每个部分的含义,尤其是涉及到WiFi连接状态和漫游的信息。 首先,用户给出的日志是: 03-02 17:45:44.509 01730 02099 D WifiClientModeImpl[127206165:wlan0]: ClientModeImpl$L2ConnectedState screen=on 0 0 BSSID=a2:4a:87:fc:67:c7 Target Bssid=any Last Bssid=a2:4a:87:fc:67:c7 roam=false 我需要拆解这个日志的结构。开头是时间戳,然后是进程ID和线程ID,接着是调试级别D和类名WifiClientModeImpl,可能还有实例标识符[127206165:wlan0]。后面的消息内容描述了客户端模式的状态,特别是L2ConnectedState,也就是第二层连接状态。 接下来,消息中的各个键值对需要逐一解析。首先是screen=on,表示屏幕处于开启状态。后面的两个0暂时确定具体含义,可能需要上下文。然后BSSID是当前连接的接入点的MAC地址a2:4a:87:fc:67:c7。Target Bssid=any可能表示设备在寻找任何目标BSSID进行连接,而Last Bssid同样是当前的BSSID,这可能是在记录之前连接的BSSID。最后是roam=false,说明此时没有发生漫游。 用户的问题是关于漫游的部分,所以需要重点分析roam=false的含义。漫游通常指设备在移动时自动切换到信号更强的另一个接入点,而此处显示漫游未发生,可能意味着设备当前连接的BSSID稳定,没有触发漫游机制。需要确认日志中其他参数是否支持这一结论,比如是否Target Bssid被设置为特定值,但这里显示为any,可能意味着设备没有指定目标,或者处于可接受任何的状态。 接下来,我应该考虑Android系统中WiFi漫游的工作机制。通常,系统会根据信号强度、网络质量等因素决定是否漫游。当信号弱到一定程度,设备会搜索更好的AP,并可能触发漫游。在此日志中,roam=false说明此时没有进行漫游操作,可能因为当前连接质量良好,或者设备处于静止状态,信号没有明显变化。 另外,L2ConnectedState指的是数据链路层(第二层)已连接的状态,说明设备已经建立了稳定的网络连接。screen=on可能影响设备的电源管理策略,比如在屏幕开启时更积极地维持连接或扫描网络,但这里并未触发漫游。 可能需要进一步考虑的是,Target Bssid=any和Last Bssid相同是否正常。通常情况下,如果设备在考虑漫游,Target Bssid可能会指向另一个特定的BSSID,而这里设置为any可能表示系统尚未确定目标,或者处于空闲状态,没有漫游的必要。 总结来说,该日志条目表明设备当前处于稳定的WiFi连接状态,没有进行漫游。漫游未被触发的原因可能是信号良好,或系统判断无需切换。需要结合其他日志或上下文信息来全面评估漫游行为,但单从这条日志来看,漫游未发生。</think>让我们逐步分析您提供的日志条目,重点关注与WiFi漫游相关的信息: 1. **日志结构拆解** $$ \text{03-02 17:45:44.509} \quad \text{01730} \quad \text{02099} \quad \text{D} \quad \text{WifiClientModeImpl[127206165:wlan0]} $$ 表示: - 时间戳:2023年3月2日 17:45:44.509 - 进程ID:01730 - 线程ID:02099 - 调试级别:D(DEBUG) - 模块标识:WifiClientModeImpl实例 + 网络接口wlan0 2. **关键参数解析** - `ClientModeImpl$L2ConnectedState`:当前处于数据链路层(Layer2)已连接状态 - `screen=on`:设备屏幕处于亮屏状态 - `BSSID=a2:4a:87:fc:67:c7`:当前连接WiFi接入点MAC地址 - `Target Bssid=any`:未指定目标切换的BSSID - `Last Bssid=a2:4a:87:fc:67:c7`:最近一次成功连接的BSSID与当前相同 - **`roam=false`**:核心漫游标识,表示当前未触发漫游机制 3. **漫游机制详解** - 触发条件:当信号强度(RSSI)低于阈值(通常约-70dBm)时,Android会启动漫游扫描 - 决策因素:包括但限于 $$ \text{信号质量} \geq \text{阈值} + \text{滞后值} $$ $$ \text{目标AP评分} > \text{当前AP评分} + \text{切换阈值} $$ - 日志中的`roam=false`表明: - 当前AP信号质量良好 - 未检测到更优候选AP - 设备处于稳定连接状态 4. **关联参数分析** - `Target Bssid=any`:表示系统未锁定特定切换目标 - `Last Bssid`与当前BSSID一致:说明最近未发生过漫游切换 - 屏幕亮屏状态(`screen=on`)时,系统会: $$ \text{缩短扫描间隔} \quad \text{vs} \quad \text{灭屏状态的节能模式} $$ 5. **漫游优化建议** - 若频繁出现意外漫游,可检查: $$ \text{roam\_rssi\_threshold} \quad (\text{默认-70dBm}) $$ $$ \text{roam\_delta} \quad (\text{信号差异阈值}) $$ - 调试命令示例: ```bash adb shell cmd wifi set-verbose-logging enable adb logcat | grep -i "roam" ``` 此日志条目表明设备当前处于稳定的WiFi连接状态,未触发漫游机制。如需深入分析漫游行为,建议连续捕获包含`roam=true`的日志序列,观察信号强度变化和候选AP评估过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值