我得到了一个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();
}
}
如果设备处于飞行模式(或者假设在没有可用网络的其他情况下),cm.getActiveNetworkInfo()将为空,因此您需要添加一个空检查。
修改(Eddie的解决方案)如下:
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
在AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
还有一点,如果你在给定的时间点绝对需要一个网络连接,那么使用netInfo.isConnected()而不是netInfo.isConnectedOrConnecting可能会更好。不过,我想这取决于个人用例。
下面是我用于可达性检查的Kotlin版本,
芬兰湾的科特林MyReachability
object MyReachability {
private val REACHABILITY_SERVER = "http://google.com" // can be any URL you want
private fun hasNetworkAvailable(context: Context): Boolean {
val service = Context.CONNECTIVITY_SERVICE
val manager = context.getSystemService(service) as ConnectivityManager?
val network = manager?.activeNetworkInfo
Log.d(classTag, "hasNetworkAvailable: ${(network != null)}")
return (network != null)
}
fun hasInternetConnected(context: Context): Boolean {
if (hasNetworkAvailable(context)) {
try {
val connection = URL(REACHABILITY_SERVER).openConnection() as HttpURLConnection
connection.setRequestProperty("User-Agent", "Test")
connection.setRequestProperty("Connection", "close")
connection.connectTimeout = 1500
connection.connect()
Log.d(classTag, "hasInternetConnected: ${(connection.responseCode == 200)}")
return (connection.responseCode == 200)
} catch (e: IOException) {
Log.e(classTag, "Error checking internet connection", e)
}
} else {
Log.w(classTag, "No network available!")
}
Log.d(classTag, "hasInternetConnected: false")
return false
}
}
您甚至可以根据策略和限制将REACHABILITY_SERVER作为参数传递,例如,当您在中国时,您可以检查https://baidu.com而不是https://google.com。
调用示例中,
val webLoaderThread = Thread {
if (MyReachability.hasInternetConnected(this)){
runOnUiThread {
//mWebView.loadUrl(LANDING_SERVER) // connected
}
} else {
runOnUiThread {
//showDialogNoNetwork() // not connected
}
}
}
webLoaderThread.start()
安卓系统权限
不要忘记将以下权限添加到你的AndroidManifest.xml中
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
我做了这个代码,它是最简单的,它只是一个布尔值。
通过询问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;
}
对我来说,在Activity类中检查连接状态并不是一个好的实践,因为
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
应该在那里调用,或者您需要下推您的活动实例(上下文)到连接处理程序类,以能够检查那里的连接状态
当没有可用的连接(wifi,网络)时,我捕捉到UnknownHostException异常:
JSONObject jObj = null;
Boolean responded = false;
HttpGet requestForTest = new HttpGet("http://myserver.com");
try {
new DefaultHttpClient().execute(requestForTest);
responded = true;
} catch (UnknownHostException e) {
jObj = new JSONObject();
try {
jObj.put("answer_code", 1);
jObj.put("answer_text", "No available connection");
} catch (Exception e1) {}
return jObj;
} catch (IOException e) {
e.printStackTrace();
}
通过这种方式,我可以处理这种情况连同其他情况在同一类(我的服务器总是响应回json字符串)