我得到了一个AsyncTask,应该检查对主机名的网络访问。但是doInBackground()永远不会超时。有人知道吗?
public class HostAvailabilityTask extends AsyncTask<String, Void, Boolean> {
private Main main;
public HostAvailabilityTask(Main main) {
this.main = main;
}
protected Boolean doInBackground(String... params) {
Main.Log("doInBackground() isHostAvailable():"+params[0]);
try {
return InetAddress.getByName(params[0]).isReachable(30);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean... result) {
Main.Log("onPostExecute()");
if(result[0] == false) {
main.setContentView(R.layout.splash);
return;
}
main.continueAfterHostCheck();
}
}
我已经应用了@Levit提供的解决方案,并创建了不会调用额外Http请求的函数。
它将解决无法解析主机的错误
public static boolean isInternetAvailable(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork == null) return false;
switch (activeNetwork.getType()) {
case ConnectivityManager.TYPE_WIFI:
if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
isInternet())
return true;
break;
case ConnectivityManager.TYPE_MOBILE:
if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
isInternet())
return true;
break;
default:
return false;
}
return false;
}
private static boolean isInternet() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
Debug.i(exitValue + "");
return (exitValue == 0);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
现在叫它,
if (!isInternetAvailable(getActivity())) {
//Show message
} else {
//Perfoem the api request
}
我做了这个代码,它是最简单的,它只是一个布尔值。
通过询问if(isOnline()){
如果存在连接,并且可以连接到页面,则会得到状态代码200(稳定连接)。
确保添加正确的INTERNET和ACCESS_NETWORK_STATE权限。
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(3000);
urlc.connect();
if (urlc.getResponseCode() == 200) {
return new Boolean(true);
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return false;
}
我已经尝试了近5+不同的android方法,发现这是谷歌提供的最佳解决方案,特别是android:
try {
HttpURLConnection urlConnection = (HttpURLConnection)
(new URL("http://clients3.google.com/generate_204")
.openConnection());
urlConnection.setRequestProperty("User-Agent", "Android");
urlConnection.setRequestProperty("Connection", "close");
urlConnection.setConnectTimeout(1500);
urlConnection.connect();
if (urlConnection.getResponseCode() == 204 &&
urlConnection.getContentLength() == 0) {
Log.d("Network Checker", "Successfully connected to internet");
return true;
}
} catch (IOException e) {
Log.e("Network Checker", "Error checking internet connection", e);
}
它比任何其他可用的解决方案都更快、高效和准确。
不需要太复杂。最简单的框架方式是使用ACCESS_NETWORK_STATE权限并创建一个连接的方法
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null &&
cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
如果您有特定的主机和连接类型(wifi/移动),也可以使用requestRouteToHost。
你还需要:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
在你的android清单中。