判断网络是否可用引发的Bug

203 阅读1分钟

如何判断网络是否可用

1、通过访问系统的ConnectivityManager

/**  
 * 检查网络是否可用  
 *  
 * @param context 应用上下文  
 * @return true 如果网络可用,否则返回 false 
*/
 
 private fun isNetworkOnline(context: Context): Boolean {  
    val connectivityManager =  
        context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager  
    val activeNetworkInfo = connectivityManager.activeNetworkInfo  
    return activeNetworkInfo != null && activeNetworkInfo.isConnected  
}

2、ping 一个ip

fun isNetworkOnline(): Boolean {  
    val runtime = Runtime.getRuntime()  
    try {  
        val ipProcess = runtime.exec("ping -c 1 -w 1 1.1.1.1")  //这里举例 1.1.1.1
        val exitValue = ipProcess.waitFor()  
        return exitValue == 0  
    } catch (e: Exception) {  
        e.printStackTrace()  
    }
    return false  
}

或者这样

Thread {  
    try {  
        val address = InetAddress.getByName("www.tencent.com")  // 举例用的是腾讯的
        val isReachable = address.isReachable(5000) // 设置超时时间为5秒  
        println("network InetAddress $isReachable")  
    } catch (e: IOException) {  
        e.printStackTrace()  
    }  
}.start()

背景

公司有一套网络请求库(封装了okhttp3)提供给很多app 使用。 提供的库中每次进行网络请求都要判断机器是否可以上网。(这导致了后面出现的问题)

@Override  
public void onStart(Request<T, ? extends Request> request) {  
    if (isNetworkOnline()) {  // 这里是 ping 一个ip地址判断网络是否可用
        callback.onNetWorkError();  
    }
}

问题:某些客户所在的场景会对ip的归属地做了限制(访问不了这些ip),这就导致我负责的apk 用不了。(有苦说不清)

解决方案:

  1. 直接去掉 isNetworkOnline() 判断网络这一步
  2. ping 多几个ip (国内的、海外的都要有) ,这种方法我觉得还是不太好

总结

进行网络请求的时候一般没必要先判断网络是否可用,因为大多数网络库(如Retrofit、OkHttp等)会自动处理网络不可用的情况,并返回适当的错误信息。如果偏要判断网络是否可用建议使用ConnectivityManager

建议:在使用公司封装好的库的时候有什么不懂的疑问的地方最好问清楚一点,不然出了问题不知道找谁。