Unknow Host Exception
Issue
Wifi开关打开着同时数据网络开启着,没有Wi-Fi可以使用,使用数据网络请求Wi-Fi密码,在连上Wi-Fi后忘记密码重新使用数据网络请求便会失败。一直使用6.0的机器测试,jni报异常:Unable to resolve host “xxx.yyy.com”: No address associated with hostname,由于jni的调试不方便,翻译成java后找问题捕获异常:Unknow Host Exception。
Answer
No.1 网上查找需要添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
检查AndroidManifest.xml中的网络相关的权限是有添加的
<!-- 网络相关权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<!-- 地理位置(6.0以上wifi必须) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
No.2 也曾考虑过是否和数据网络的代理有关,但是log打出来代理是关着的。
No.3 找到一个帖子里遇到的问题几乎一致(http://bbs.csdn.net/topics/390687083),贴中内容说是因为服务器端防火墙的原因,将防火墙关闭就好了。咨询了公司服务器端的同事,同事也并很清楚这里说的防火墙指的是啥,如果是指端口那么常用的端口都是开着的。
No.4 无意中换了一个5.x系统的机器测试到捕获到的异常不一样了,socket failed: errno 64 (Machine is not on the network),根据关键字找到(http://stackoverflow.com/questions/38572938/android-network-not-reconnecting-when-wifi-drops),指代码中设置了通过指定网络作网络请求。
connectivityManager.setProcessDefaultNetwork(net);
全局搜索发现代码中在监听网络状态的广播中确实有作这样的设置:
private ConnectivityStatus getConnectivityStatus(final Context context) {
final String service = Context.CONNECTIVITY_SERVICE;
final ConnectivityManager manager = (ConnectivityManager) context.getSystemService(service);
final NetworkInfo networkInfo = manager.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isAvailable()) {
return ConnectivityStatus.OFFLINE;
}
if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// for (Network net : manager.getAllNetworks()) {
// // 可以通过下面代码将app接下来的请求都绑定到这个网络下请求
// if (Build.VERSION.SDK_INT >= 23) {
//// manager.bindProcessToNetwork(net);
// } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// // 23后这个方法舍弃了
//// ConnectivityManager.setProcessDefaultNetwork(net);
// }
// }
// }
return ConnectivityStatus.WIFI_CONNECTED;
} else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
return ConnectivityStatus.MOBILE_CONNECTED;
}
return ConnectivityStatus.OFFLINE;
}
这也解释得通为啥第一次使用数据网络请求是正常的,连接过一次Wi-Fi后就无法使用数据网络了。这段代码的添加已经不记得,查找提交记录发现是自己几个月前添加到,估计当时考虑到节省数据流量只通过网络访问。最后,将其中设定的只允许通过Wi-Fi访问的限制注释掉就OK了。