最近在测试一个功能的时候,偶然发现,网络连接都正常且能上网的情况下,居然提示网络不通,最开始以为只是偶然情况,就没太在意,后来发现能够重现,然后就决定研究一下,还真研究出一些问题
查看代码
然后就看了一下程序判断网络是否连接的这一块代码,代码如下,很简单也很常规:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/**
* 判断网络是否连接
*
* @param context
* @return
**/
public static boolean isNetworkConnected(Context context) {
try {
ConnectivityManager connectivityManager = (ConnectivityManager)
context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected;
} catch (Exception e) {
return false;
}
}
这就是普通的判断网络是否连接(注意,只是判断是否连接,至于能不能上网并不能判断)的,用的也都是Android自身的API来判断的,按说没有什么问题啊,但是就是这个方法一直返回false。。。
分析
我首先想到可能的原因是权限问题,因为我用的是Android 6.0的测试机,Android 6.0之后很多权限不是需要程序主动去申请,用户同意之后才会获得,我就想着是不是因为没有获取到访问网络信息的权限,所以在获取网络连接情况的代码短的地方抛出异常了,导致返回的一直是false,带着疑问,我就调试了一下,发现程序并不会抛出异常,都是正常执行,networkInfo也不为null,networkInfo.isConnected返回的就是false,这下就有意思了,我看了一下NetworkInfo类的实例方法isConnected(),也没有被deprecated,也没有说可能会不准确之类的啊,就觉得更郁闷了。。。
然后我想看看其他手机是不是也是这样的,我试了一台Android4.3的vivo手机和一台同样系统版本的三星手机,都是正常的,然后又测试了一台Android 6.0的nexus手机,也是ok的,就唯独6.0的小米系统返回的是false。。。
为了更进一步确认是只有连接wifi的情况下会这样,还是说移动网络也会这样,我就把我的6.0的小米测试机的wifi关掉,用我的联通4G来测试,结果还是一样,isConnected依然返回false。
因为这个判断网络是否连接的方法,在应用打开的时候也会调用,我发现在应用打开的时候调用返回的就是true,都是正常的,唯独退出应用之后,后台定时任务每次调用的时候返回的就是false了,网上有说调用isConnectedOrConnecting
,结果是一样的
总结一下就是,在6.0的小米手机上,正常在应用内调用isConnected()返回值都是正常的,等退出应用之后,通过定时任务调用就会在连接的情况下也返回false,其他测试手机则不会。
于是我猜测:可能是miui为了流畅度或者是低耗电量等方面的优化,故意这样设计的,就是为了防止一些应用在后台定时判断网络连接的情况下,做一些网络请求任务,造成高耗电又影响流畅性,所以小米系统基本在所有应用都退出,回到桌面的情况下,有可能会短暂的禁掉当前的网络链接,当然这也只是猜测而已。
如何应对
如果在小米6.0的机器上,大家非要在后台判断网络连接情况,那么目前来看,最保险的做法就是在程序中请求一下常用的网站,比如baidu,或者ping一下,来判断网络的真正链接情况,实现很简单,网上有很多,我在这里就不写了,当然我亲测这种方法是有效的