在实际开发中遇到iOS下网络状态正常,在android下却获取失败的错误。通过NetInfo获取的网路状态,iOS下有四种状态,android下却有10几种状态,且大小写都不同......麻蛋,好蛋疼。。。
Android可获取的状态比较多,上面的status可能有如下的值,直接把文档贴出来了:
+ NONE - 设备处于离线状态
+ BLUETOOTH - 蓝牙数据连接
+ DUMMY - 模拟数据连接
+ ETHERNET - 以太网数据连接
+ MOBILE - 移动网络数据连接
+ MOBILE_DUN - 拨号移动网络数据连接
+ MOBILE_HIPRI - 高优先级移动网络数据连接
+ MOBILE_MMS - 彩信移动网络数据连接
+ MOBILE_SUPL - 安全用户面定位(SUPL)数据连接
+ VPN - 虚拟网络连接。需要Android5.0以上
+ WIFI - WIFI数据连接
+ WIMAX - WiMAX数据连接
+ UNKNOWN - 未知数据连接
IOS端网络状态
none - 设备处于离线状态。
wifi - 设备处于联网状态且通过wifi链接,或者是一个iOS的模拟器。
cell - 设备是通过Edge、3G、WiMax或是LTE网络联网的。
unknown - 发生错误,网络状况不可知
1.NetInfo实现过程
![screen shot 2015-12-16 at 2 26 28 am](https://cloud.githubusercontent.com/assets/4964340/11823867/8031bf76-a39c-11e5-85a0-47211a6beadc.png)
2. iOS下网络状态获取错误
step 1:
NetInfo.isConnected.fetch().then().done((network_state) => {
this.network_state = network_state //ios下总是返回unknown
});
step 2:
NetInfo.isConnected.addEventListener('change', (network_state) => {
this.network_state = network_state
});
iOS
step1总是返回unknown,且step1、step2的执行顺序不确定:
结果1: step1="unknown" step2="wifi" 覆盖后结果 => wifi
结果2: step2="wifi" step1="unknown" 覆盖后结果 => unknown
android
android下,step1正常返回结果WIFI,step2的addEventListener不会被调用
所以这里采用比较取巧的做法:
NetInfo.isConnected.fetch().then().done(() => {
NetInfo.isConnected.addEventListener('change', dispatchConnected);
});
3.RN分装网络状态
/**
* Created by evilcode on 23/03/2017.
* 网络状态的处理
Android可获取的状态比较多,上面的status可能有如下的值,直接把文档贴出来了:
+ NONE - 设备处于离线状态
+ BLUETOOTH - 蓝牙数据连接
+ DUMMY - 模拟数据连接
+ ETHERNET - 以太网数据连接
+ MOBILE - 移动网络数据连接
+ MOBILE_DUN - 拨号移动网络数据连接
+ MOBILE_HIPRI - 高优先级移动网络数据连接
+ MOBILE_MMS - 彩信移动网络数据连接
+ MOBILE_SUPL - 安全用户面定位(SUPL)数据连接
+ VPN - 虚拟网络连接。需要Android5.0以上
+ WIFI - WIFI数据连接
+ WIMAX - WiMAX数据连接
+ UNKNOWN - 未知数据连接
IOS端网络状态
none - 设备处于离线状态。
wifi - 设备处于联网状态且通过wifi链接,或者是一个iOS的模拟器。
cell - 设备是通过Edge、3G、WiMax或是LTE网络联网的。
unknown - 发生错误,网络状况不可知
*** 存在问题:
step 1:
NetInfo.isConnected.fetch().then().done((network_state) => {
this.network_state = network_state //ios下总是返回unknown
});
step 2:
NetInfo.isConnected.addEventListener('change', (network_state) => {
this.network_state = network_state
});
iOS
step1总是返回unknown,且step1、step2的执行顺序不确定:
结果1: step1="unknown" step2="wifi" 覆盖后结果 => wifi
结果2: step2="wifi" step1="unknown" 覆盖后结果 => unknown
android
android下,step1正常返回结果WIFI,step2的addEventListener不会被调用
所以这里采用比较取巧的做法:
NetInfo.isConnected.fetch().then().done(() => {
NetInfo.isConnected.addEventListener('change', dispatchConnected);
});
*/
import {
NetInfo,
} from 'react-native';
var Platform = require('Platform')
var UtilsNetwork = {}
/**
* 注册网络的状态变化监听
* @param cb_network_state (network_state) => { ... } 直接获取网络的状态
* @param cb_network_state_change (network_state) => { ... } 网络状态改变时进入的回调
*/
UtilsNetwork.registNetworkStateListener = function(cb_network_state, cb_network_state_change) {
NetInfo.fetch().done((net_state) => {
if (cb_network_state) {
cb_network_state(net_state)
}
NetInfo.addEventListener('change',
(net_state) => {
if (cb_network_state) {
cb_network_state(net_state)
}
if (cb_network_state_change) {
cb_network_state_change(net_state)
}
}
)
})
}
/**
* 当前手机网络连接状态 NetInfo状态 'none'、'wifi'、'cell'、'unknown'
* http://reactnative.cn/docs/0.40/netinfo.html#content
* @returns {boolean|*}
*/
UtilsNetwork.isNetworkConnected = function(network_state) {
if (!network_state)
return false
let ns = network_state.toUpperCase()
if (Platform.OS === 'ios') {
if (ns == 'WIFI' ||
ns == 'CELL')
return true
} else if (Platform.OS == 'android') {
let no_network = {
'NONE': 1,
'UNKNOWN': 1,
'BLUETOOTH': 1,
}
if (no_network[ns])
return false
else
return true
}
return false
}
/**
* 设备处于联网状态且通过wifi链接,或者是一个iOS的模拟器。
* @param network_state {string} 网络状态
* @returns {boolean}
*/
UtilsNetwork.isNetworkWifi = function(network_state) {
if (!network_state)
return false
let ns = network_state.toUpperCase()
return ns == 'WIFI'
}
/**
* 设备是通过Edge、3G、WiMax或是LTE网络联网的。
Android下
+ MOBILE - 移动网络数据连接
+ MOBILE_DUN - 拨号移动网络数据连接
+ MOBILE_HIPRI - 高优先级移动网络数据连接
+ MOBILE_MMS - 彩信移动网络数据连接
+ MOBILE_SUPL - 安全用户面定位(SUPL)数据连接
* @param network_state {string} 网络状态
* @returns {boolean}
*/
UtilsNetwork.isNetworkCell = function(network_state) {
if (!network_state)
return false
let ns = network_state.toUpperCase()
if (Platform.OS === 'ios') {
return ns == 'CELL'
} else if (Platform.OS == 'android') {
return ns.contains('MOBILE')
}
return false
}
export default UtilsNetwork
参考链接:
https://facebook.github.io/react-native/releases/0.23/docs/netinfo.html
http://m.blog.csdn.net/article/details?id=52587009
todo:simulator中获取不正常,真机中是没有问题的
https://stackoverflow.com/questions/42642034/check-for-internet-connection-returns-wrong-results
网友评论