最近项目中有一个网络判断的需求,因为终端只能连接wifi,wifi即使连接上也可能会出现不能连接网络的问题,所以需要进行网络连接的判断。
ping的相关知识
使用ping检验网络是否可以连接
ping就是检测客户端是否可以上网。
那么我们就上代码
该段代码来自http://blankj.com
导入常用工具包compile 'com.blankj:utilcode:1.9.8'
这个里边有各种各样的常用的工具类,下边的代码是NetworkUtils
的一个方法;
/**
* 判断网络是否可用
* <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
* <p>需要异步ping,如果ping不通就说明网络不可用</p>
*
* @param ip ip地址(自己服务器ip),如果为空,ip为阿里巴巴公共ip
* @return {@code true}: 可用<br>{@code false}: 不可用
*/
public static boolean isAvailableByPing(String ip) {
if (ip == null || ip.length() <= 0) {
ip = "223.5.5.5";// 阿里巴巴公共ip
}
ShellUtils.CommandResult result = ShellUtils.execCmd(String.format("ping -c 1 %s", ip), false);
boolean ret = result.result == 0;
if (result.errorMsg != null) {
Log.d("NetworkUtils", "isAvailableByPing() called" + result.errorMsg);
}
if (result.successMsg != null) {
Log.d("NetworkUtils", "isAvailableByPing() called" + result.successMsg);
}
return ret;
}
这段代码完全可以作为网络检测的使用,可是我在使用这段代码的时候偶尔会遇到anr的问题。出现anr就说明在主线程做了耗时操作,这是我没有将这段代码放到子线程造成的问题。其实ping也就相当于去请求网络,跟普通的接口请求差不多,当网络比较慢的时候就会消耗时间,放在主线程就会造成anr。
在修改bug的时候我对这段代码进行了一些修改:
* 判断网络是否可用
* <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
* <p>需要异步ping,如果ping不通就说明网络不可用</p>
*
* @param ip ip地址(自己服务器ip),如果为空,ip为阿里巴巴公共ip
* @return {@code true}: 可用<br>{@code false}: 不可用
*/
public static boolean isAvailableByPing(String ip) {
if (ip == null || ip.length() <= 0) {
ip = "223.5.5.5";// 阿里巴巴公共ip
}
Runtime runtime = Runtime.getRuntime();
Process ipProcess = null;
try {
//-c 后边跟随的是重复的次数,-w后边跟随的是超时的时间,单位是秒,不是毫秒,要不然也不会anr了
ipProcess = runtime.exec("ping -c 3 -w 3 "+ip);
int exitValue = ipProcess.waitFor();
Log.i("Avalible", "Process:" + exitValue);
return (exitValue == 0);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
//在结束的时候应该对资源进行回收
if (ipProcess != null) {
ipProcess.destroy();
}
runtime.gc();
}
return false;
}
只需要把这个方法引用到子线程中就行了,其实不引用也可以,因为在这里设定了超时时间为3秒。但是最好是放到子线程里边。