写下这个标题我脸都红了..
不来点干货怎能留下你们呢,客官请留步,好酒好肉马上来。
QA大大们提了个BUG:打开WIFI条件下,疯狂点击便携式热点按钮,接着按钮就再也点不动了。
跟进代码一看,哎呀我去,没人改过,这是google写的。在最新的5.0系统中测试,一样存在这个问题。卧槽,QA太牛了,google好几年没测出来的BUG你都能发现。
好吧,接下来又是苦逼的求知之旅。
根据“便携式 WLAN 热点” 全文搜索找到对应的资源
再根据 name=”wifi_tether_checkbox_text” 找到对应的xml:tether_prefs.xml,看来这个xml就是我们的页面了,再全局搜索tether_prefs 定位到 TetherSettings。很不错,已经摸到大腿了。接下来都是java那就好办了,两三步定位到代码 425 行
public boolean onPreferenceChange(Preference preference, Object value) {
boolean enable = (Boolean) value;
if (enable) {
startProvisioningIfNecessary(WIFI_TETHERING);
} else {
mWifiApEnabler.setSoftapEnabled(false);
}
return false;
}
每次点击就是调用这个方法。好的,继续跟进,发现设置热点打开关闭主要是通过 WifiApEnabler 这个类中的 setSoftapEnabled()这个方法。从上面可以看出来,点击关闭的时候直接就调用 mWifiApEnabler.setSoftapEnabled(false); ,打开的时候实际也是调用这个方法,详细代码不多说。方法的代码如下,关键部分请看注释
public void setSoftapEnabled(boolean enable) {
final ContentResolver cr = mContext.getContentResolver();
/**
* Disable Wifi if enabling tethering
*/
int wifiState = mWifiManager.getWifiState();//获取wifi状态,因为打开热点是要关闭wifi的
if (enable && ((wifiState == WifiManager.WIFI_STATE_ENABLING) ||
(wifiState == WifiManager.WIFI_STATE_ENABLED))) {//若wifi为打开或打开中状态
mWifiManager.setWifiEnabled(false);//关闭wifi
Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 1);//记录WIFI的状态
}
if (mWifiManager.setWifiApEnabled(null, enable)) {//判断是否能打开热点(飞行模式不能打开)
/* Disable here, enabled on receiving success broadcast */
mCheckBox.setEnabled(false);//设置不能点击,在接受到热点打开后设置可以点击,具体看源码handleWifiApStateChanged()方法
} else {
mCheckBox.setSummary(R.string.wifi_error);
}
/**
* If needed, restore Wifi on tether disable
*/
if (!enable) {//关闭热点
int wifiSavedState = 0;
try {
wifiSavedState = Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE);//获得打开热点前wifi的状态
} catch (Settings.SettingNotFoundException e) {
;
}
if (wifiSavedState == 1) {
mWifiManager.setWifiEnabled(true);//打开wifi
Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);//状态恢复
}
}
}
乍一看,代码没有任何逻辑问题,那为何疯狂点击后会无法再次点击呢?这是这个BUG的难点,似乎找不到理由。后根据多次测试梳理逻辑,终于找到一丝蛛丝马迹。
打开热点必须关闭WIFI,所以BUG是在关闭热点后,马上再次打开情况下发生的。这时候根据自己添加的代码LOG,发现再次打开时Wifi的状态是关闭。这是该BUG出现的关键。按逻辑,若WIFI的原始状态是打开,点击关闭热点会重新打开Wifi,此时获取Wifi的状态应该是打开中,但我猜想可能涉及到多线程操作,在快速点击时这里获取到的Wifi状态是关闭。
由于获取到错误的Wifi状态,所以Wifi明明是打开的,却没有去关闭,造成 设置按钮不可点击-》打开热点操作后,获取不到热点打开成功的广播,造成按钮无法还原,所以再也不能点了,只能退出页面重进。
说了这么多?那该怎么解决呢?
解BUG最好是从根本上解决,但这根本涉及的太深了,搞不定 – – ~
没办法,只能贴块狗皮膏药了,不管黑猫白猫,能抓老鼠就是好猫~不管啥办法,能解决BUG就是好方法。
回头看BUG,点击关闭热点会重新打开Wifi,但是此时Wifi状态是关闭,所以造成后面无法点击,但是Wifi还是会重新打开的!所以我们可以监听Wifi打开的广播,在收到广播后无脑的将按钮设置为可以点击!这样就完美解决了Google的BUG了!嘿嘿,希望能帮到有需要的童鞋。