Android上的http连接超时不起作用
我正在编写一个连接到web服务的应用程序,如果它不能连接,我不希望它等待太久。 因此我设置了httpparams的connectionTimeout。 但它似乎没有任何影响。
要testing我暂时closuresWLAN。 应用程序尝试连接相当一段时间(比我想要的3秒多),然后抛出一个UnknownHostException。
这是我的代码:
try{ HttpClient httpclient = new DefaultHttpClient(); HttpParams params = httpclient.getParams(); HttpConnectionParams.setConnectionTimeout(params, 3000); HttpConnectionParams.setSoTimeout(params, 3000); httppost = new HttpPost(URL); StringEntity se = new StringEntity(envelope,HTTP.UTF_8); httppost.setEntity(se); //Code stops here until UnknownHostException is thrown. BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient.execute(httppost); HttpEntity entity = httpResponse.getEntity(); return entity; }catch (Exception e){ e.printStackTrace(); }
任何人有什么想法我错过了?
试着这样做:
HttpPost httpPost = new HttpPost(url); StringEntity se = new StringEntity(envelope,HTTP.UTF_8); httpPost.setEntity(se); HttpParams httpParameters = new BasicHttpParams(); // Set the timeout in milliseconds until a connection is established. int timeoutConnection = 3000; HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); // Set the default socket timeout (SO_TIMEOUT) // in milliseconds which is the timeout for waiting for data. int timeoutSocket = 3000; HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters); BasicHttpResponse httpResponse = (BasicHttpResponse) httpClient.execute(httpPost); HttpEntity entity = httpResponse.getEntity(); return entity;
然后你可以捕获一个可能的ConnectTimeoutException
。
有了标记的解决scheme,我仍然在30秒以后得到一个UnknownHostException。 在这种情况下,该设备连接到无线路由器,但没有互联网接入。
采取的方法是启动一个AsyncTask,只是试图parsing主机名。 阻塞调用每250毫秒检查一次是否成功,4秒后取消任务并返回。
这是我做的解决它的方法:
private boolean dnsOkay = false; private static final int DNS_SLEEP_WAIT = 250; private synchronized boolean resolveDns(){ RemoteDnsCheck check = new RemoteDnsCheck(); check.execute(); try { int timeSlept = 0; while(!dnsOkay && timeSlept<4000){ //Log.d("RemoteDnsCheck", "sleeping"); Thread.sleep(DNS_SLEEP_WAIT); timeSlept+=DNS_SLEEP_WAIT; //Log.d("RemoteDnsCheck", "slept"); } } catch (InterruptedException e) { } if(!dnsOkay){ Log.d("resolveDns", "cancelling"); check.cancel(true); Log.d("resolveDns", "cancelled"); } return dnsOkay; } private class RemoteDnsCheck extends AsyncTask<Void, Void, Void>{ @Override protected Void doInBackground(Void... params) { try { Log.d("RemoteDnsCheck", "starting"); dnsOkay = false; InetAddress addr = InetAddress.getByName(baseServiceURL); if(addr!=null){ Log.d("RemoteDnsCheck", "got addr"); dnsOkay = true; } } catch (UnknownHostException e) { Log.d("RemoteDnsCheck", "UnknownHostException"); } return null; } }
然后,任何时候我想要做一个networking调用,这是在函数的开始部分调用的:
if(!resolveDns()){ return null; }
请参阅: https : //stackoverflow.com/a/20031077/2609238
这个问题可能在Apache HTTP Client中。 请参阅HTTPCLIENT-1098。 在4.1.2中修复。
出于logging目的,超时例外尝试反向DNS IP。 这需要额外的时间,直到实际发生exception。
这个方法适用于我:
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); // Set the default socket timeout (SO_TIMEOUT)