
我有一个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(); } }解决方法:
网络连接/互联网访问
> isConnectedOrConnecting()(在大多数答案中使用)检查任何网络连接
>要了解这些网络中是否有任何网络访问,请使用以下方法之一
A)Ping服务器(简单)
// ICMP public boolean isOnline() { Runtime runtime = Runtime.getRuntime(); try { Process ipProcess = runtime.exec("/system/bin/Ping -c 1 8.8.8.8"); int exitValue = ipProcess.waitFor(); return (exitValue == 0); } catch (IOException e) { e.printstacktrace(); } catch (InterruptedException e) { e.printstacktrace(); } return false;}可以在主线程上运行
– 不适用于某些旧设备(galays S3等),如果没有可用的互联网,它会阻塞一段时间.
B)连接到Internet上的套接字(高级)
// TCP/http/DNS (depending on the port, 53=DNS, 80=http, etc.)public boolean isOnline() { try { int timeoutMs = 1500; Socket sock = new Socket(); SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53); sock.connect(sockaddr, timeoutMs); sock.close(); return true; } catch (IOException e) { return false; }}非常快(无论哪种方式),适用于所有设备,非常可靠
– 无法在UI线程上运行
这在每台设备上都非常可靠,而且速度非常快.它需要在单独的任务中运行(例如scheduledexecutorservice或AsyncTask).
可能的问题
>真的够快吗?
是的,非常快;-)
>除了在互联网上测试一些东西之外,还没有可靠的方法来检查互联网吗?
不是我所知,但请告诉我,我会编辑我的答案.
>如果DNS关闭怎么办?
Google DNS(例如8.8.8.8)是世界上最大的公共DNS.截至2013年,它每天为1300亿个请求提供服务.我们只是说,你的应用可能不是当天的话题.
>需要哪些权限?
<uses-permission androID:name="androID.permission.INTERNET" />只是互联网访问 – 惊喜^^(顺便说一句,你有没有想过,如果没有这个许可,这里建议的一些方法甚至可能有一个关于互联网访问的远程胶水?)
额外:一次性AsyncTask示例
class InternetCheck extends AsyncTask<VoID,VoID,Boolean> { private Consumer mConsumer; public interface Consumer { voID accept(Boolean internet); } public InternetCheck(Consumer consumer) { mConsumer = consumer; execute(); } @OverrIDe protected Boolean doInBackground(VoID... voIDs) { try { Socket sock = new Socket(); sock.connect(new InetSocketAddress("8.8.8.8", 53), 1500); sock.close(); return true; } catch (IOException e) { return false; } } @OverrIDe protected voID onPostExecute(Boolean internet) { mConsumer.accept(internet); }}///////////////////////////////////////////////////////////////////////////////////// Usage new InternetCheck(internet -> { /* do something with boolean response */ });额外:一次性RxJava / RxAndroID示例(Kotlin)
fun hasInternetConnection(): Single<Boolean> { return Single.fromCallable { try { // Connect to Google DNS to check for connection val timeoutMs = 1500 val socket = Socket() val socketAddress = InetSocketAddress("8.8.8.8", 53) socket.connect(socketAddress, timeoutMs) socket.close() true } catch (e: IOException) { false } } .subscribeOn(Schedulers.io()) .observeOn(AndroIDSchedulers.mainThread())}/////////////////////////////////////////////////////////////////////////////////// // Usage hasInternetConnection().subscribe { hasInternet -> /* do something */} 总结 以上是内存溢出为你收集整理的如何检查Android上的互联网访问? InetAddress永远不会超时全部内容,希望文章能够帮你解决如何检查Android上的互联网访问? InetAddress永远不会超时所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)