Android上的Http连接超时不起作用
Posted
技术标签:
【中文标题】Android上的Http连接超时不起作用【英文标题】:Http connection timeout on Android not working 【发布时间】:2011-03-05 18:24:48 【问题描述】:我正在编写一个连接到网络服务的应用程序,如果它无法获得连接,我不希望它等待太久。因此,我设置了 httpparams 的 connectionTimeout。但这似乎没有任何作用。
为了测试,我暂时关闭了 WLAN。应用程序尝试连接很长一段时间(超过我想要的 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();
有人知道我错过了什么吗?
【问题讨论】:
【参考方案1】:尝试这样做:
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
。
【讨论】:
如何通知系统超时以及要处理什么异常? 30 多秒后我仍然收到 UnknownHostException。在这种情况下,设备已连接到 wifi 路由器,但无法访问互联网。任何线索如何使这个呼叫处理?否则我可能会退回到外部计时器...... :( @hooby3dfx 在这种情况下,外部计时器似乎是不可避免的。你有什么办法吗? @Mosquito - 我确实使用了外部计时机制并在下面发布了该解决方案。【参考方案2】:使用标记的解决方案,我在 30 多秒后仍然收到 UnknownHostException。在这种情况下,设备已连接到 wifi 路由器,但无法访问互联网。
所采取的方法是启动一个 AsyncTask,它只会尝试解析主机名。阻塞调用每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;
然后,每当我想进行网络调用时,都会在函数的开头调用它:
if(!resolveDns())
return null;
【讨论】:
这就是我要找的。谢谢老哥!【参考方案3】:见:https://***.com/a/20031077/2609238
问题可能出在 Apache HTTP 客户端中。请参阅 HTTPCLIENT-1098。已在 4.1.2 中修复。
超时异常尝试反向 DNS IP,以进行日志记录。这需要额外的时间才能真正触发异常。
【讨论】:
【参考方案4】:这个方法对我有用:
androidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;
【讨论】:
【参考方案5】:HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
【讨论】:
这不是问题的答案,因为该方法调用已经是下面代码的一部分; 另一个提示:使用代码格式更好地展示...以上是关于Android上的Http连接超时不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Android 上的 HTTP Header Cache-Control 似乎不起作用
我想在使用 kotlin 协程的 android 超时后取消一个函数,但它不起作用