我得到了一个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();
}
}
在芬兰湾的科特林:
class UtilityMethods {
companion object {
fun isConnected(activity: Activity): Boolean {
val connectivityManager: ConnectivityManager =
activity.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return null != connectivityManager.activeNetworkInfo
}
}}
在Activity类中调用isConnected如下:
UtilityMethods.isConnected(this)
内部片段类如下:
UtilityMethods.isConnected(activity)
芬兰湾的科特林实现
/**
* Function that uses ping, takes server name or ip as argument.
*
* @return [Double.MAX_VALUE] if server is not reachable. Average RTT if the server is reachable.
*
* Success output example
*
* PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
* 64 bytes from 8.8.8.8: icmp_seq=1 ttl=254 time=172 ms
* 64 bytes from 8.8.8.8: icmp_seq=2 ttl=254 time=166 ms
* 64 bytes from 8.8.8.8: icmp_seq=3 ttl=254 time=167 ms
* 64 bytes from 8.8.8.8: icmp_seq=4 ttl=254 time=172 ms
* 64 bytes from 8.8.8.8: icmp_seq=5 ttl=254 time=167 ms
* --- 8.8.8.8 ping statistics ---
* 5 packets transmitted, 5 received, 0% packet loss, time 4011ms
* rtt min/avg/max/mdev = 166.470/169.313/172.322/2.539 ms
* |________________________|
* value to parse using it.split('=')[1].trim().split(' ')[0].trim().split('/')[1].toDouble()
*/
@ExperimentalStdlibApi
fun pingServerAverageRtt(host: String): Double {
var aveRtt: Double = Double.MAX_VALUE
try {
// execute the command on the environment interface, timeout is set as 0.2 to get response faster.
val pingProcess: Process = Runtime.getRuntime().exec("/system/bin/ping -i 0.2 -c 5 $host")
// gets the input stream to get the output of the executed command
val bufferedReader = BufferedReader(InputStreamReader(pingProcess.inputStream))
bufferedReader.forEachLine {
if (it.isNotEmpty() && it.contains("min/avg/max/mdev")) { // when we get to the last line of executed ping command
aveRtt = it.split('=')[1].trim()
.split(' ')[0].trim()
.split('/')[1].toDouble()
}
}
} catch (e: IOException) {
e.printStackTrace()
}
return aveRtt
}
使用的例子
val latency = pingServerAverageRtt(ipString)
if (latency != Double.MAX_VALUE) {
//server reachable
} else {
//server not reachable
}
下面是一些现代代码,使用AsynTask来解决android崩溃的问题,当你尝试在主线程上连接并为用户引入一个带有冲洗和重复选项的警报。
class TestInternet extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(3000);
urlc.connect();
if (urlc.getResponseCode() == 200) {
return true;
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return false;
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) { // code if not connected
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("An internet connection is required.");
builder.setCancelable(false);
builder.setPositiveButton(
"TRY AGAIN",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
new TestInternet().execute();
}
});
AlertDialog alert11 = builder.create();
alert11.show();
} else { // code if connected
doMyStuff();
}
}
}
...
new TestInternet().execute();