Android连接网络流程图:
图中只关注了WiFi和以太网,连接是不分顺序的,如果以太网优先级高,就算先连接wifi后连接以太网,也会将WiFi代替掉。
重点在于优先级仲裁的阶段,各自网络配置好后,会自动到优先级仲裁的地方报道:
frameworks/base/services/java/com/android/server/ConnectivityService.java的NetworkStateTrackerHandler的handleMessage中。
所以这里将这个文件的调试全部打开将如下的值全部赋值为true.
private static final boolean DBG = true; private static final boolean VDBG = true; private static final boolean LOGD_RULES = true;
private boolean isNewNetTypePreferredOverCurrentNetType(int type) { if (DBG) { log("type = " + type); log("mNetworkPreference = " + mNetworkPreference); log("mNetConfigs[mActiveDefaultNetwork].priority = " + mNetConfigs[mActiveDefaultNetwork].priority); log(" mNetConfigs[type].priority = "+ mNetConfigs[type].priority); log("mNetworkPreference = " + mNetworkPreference); log("mActiveDefaultNetwork = " + mActiveDefaultNetwork); log("mActiveDefaultNetwork =" + mActiveDefaultNetwork); } if ((type != mNetworkPreference && mNetConfigs[mActiveDefaultNetwork].priority > mNetConfigs[type].priority) || mNetworkPreference == mActiveDefaultNetwork) return false; return true; }
转换成人类语言:
((新连接的网络类型 不 等于偏好) 且 (新连接网络类型优先级 低于 当前网络类型优先级))
或者
(偏好类型正是当前网络类型))
则不切
新连接的网络类型 = type 这里是wifi
偏好 = mNetworkPreference 这里是wifi
新连接网络类型优先级 = mNetConfigs[type].priority wifi优先级 这里是1
当前网络类型优先级 = 以太网优先级 这里是4
当前网络类型 = mActiveDefaultNetwork 这里是以太网
frameworks\base\core\res\res\values-large\config.xml 中有这种网络类型:
<string-array translatable="false" name="networkAttributes"> <item>"wifi,1,1,1,-1,true"</item> <item>"mobile,0,0,0,-1,true"</item> <item>"mobile_mms,2,0,2,60000,true"</item> <item>"mobile_supl,3,0,2,60000,true"</item> <item>"mobile_hipri,5,0,3,60000,true"</item> <item>"mobile_fota,10,0,2,60000,true"</item> <item>"mobile_ims,11,0,2,60000,true"</item> <item>"mobile_cbs,12,0,2,60000,true"</item> <item>"wifi_p2p,13,1,0,-1,true"</item> <item>"ethernet,9,9,0,-1,true"</item> </string-array>
mNetworkPreference = getPersistedNetworkPreference(); private int getPersistedNetworkPreference() { final ContentResolver cr = mContext.getContentResolver(); final int networkPrefSetting = Settings.Global .getInt(cr, Settings.Global.NETWORK_PREFERENCE, -1); if(DBG) { log("networkPrefSetting = " + networkPrefSetting); log("ConnectivityManager.DEFAULT_NETWORK_PREFERENCE = " + ConnectivityManager.DEFAULT_NETWORK_PREFERENCE); } if (networkPrefSetting != -1) { return networkPrefSetting; } return ConnectivityManager.DEFAULT_NETWORK_PREFERENCE; }这里实质读的是:Settings.Global.NETWORK_PREFERENCE在这里追踪到frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java是在这里读rameworks/base/packages/SettingsProvider/res/values/defaults.xml中的def_network_preference以下是我更改后的结果(以前是1):
<!-- 0 == mobile, 1 == wifi. 9 == eth --> <integer name="def_network_preference">9</integer>
上边的实验结果可以看出,当WiFi连接的时候,进到仲裁的地方,由于它的优先级没有ethernet的高,所以没有让它占领网卡。
(注意:修改xml文件重新编译前要将上次编译出的中间文件删除,否则不会编译进去)
然后,这个问题就解决了。