先给大家上一段代码:
ConnectivityManager conmgr = (ConnectivityManager) MovieProApplication.getContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (conmgr.getActiveNetworkInfo() == null) {
return NETWORK_UNKOWN;
}
switch (conmgr.getActiveNetworkInfo().getType()) {
case ConnectivityManager.TYPE_WIFI:
netWorkType = NETWORK_WIFI;
break;
}
return netWorkType;
这段代码是读取网络状态。但能看出来这里隐藏着一个空指针异常吗(虽然出现的几率很低),这个crash的日志如下
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.net.NetworkInfo.getType()' on a null object reference
at com.sankuai.moviepro.utils.bk.c(MovieUtils.java:783)
at com.sankuai.moviepro.utils.c.b.d(ImageQualityUtil.java:265)
at com.sankuai.moviepro.utils.c.b.c(ImageQualityUtil.java:221)
at com.sankuai.moviepro.utils.c.b.d(ImageQualityUtil.java:294)
at com.sankuai.moviepro.utils.c.b.b(ImageQualityUtil.java:83)
at com.sankuai.moviepro.utils.c.b.a(ImageQualityUtil.java:120)
at com.sankuai.moviepro.views.custom_views.by.onPreDraw(RemoteImageView.java:104)
报异常的位置是switch (conmgr.getActiveNetworkInfo().getType()),按照正常的思维,会想,我们在上面不是已经判断,为空的时候不是return了么,但事实就是这么巧两次执行conmgr.getActiveNetworkInfo()的结果如果不同呢,你会发现在上面判断不为空,在下面使用的时候就空指针了。有人会说这个几率很低,但如果这个方法比较耗时呢,读取的状态不同也就很正常了,分析完我们也可以复现这个crash了,在switch前打一个断点,然后切断网络,然后继续debug,然后就崩溃了。
解决的方法很简单,我们预先把这个读取出来,我们判断和使用的都是这个预先读取出来的networkInfo,这样就不会出现前后读取不一致的结果了。
NetworkInfo networkInfo = conmgr.getActiveNetworkInfo();