Android UnknownHostException:有没有办法设置超时?
Posted
技术标签:
【中文标题】Android UnknownHostException:有没有办法设置超时?【英文标题】:Android UnknownHostException : is there a way to set timeout? 【发布时间】:2012-03-08 23:35:02 【问题描述】:当我连接到我的网络服务以检索数据时,电话有时会断开连接、DNS 混乱等。然后我得到一个 UnknownHostException
,这非常好。
我要做的是在此处查找主机名时设置超时:
response = httpclient.execute(httpget);
我已经设置好了:
HttpConnectionParams.setConnectionTimeout(httpParameters,timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
但他们似乎没有申请HostLookUp
。有没有办法在主机查找时设置超时?
编辑
刚刚发现用户无法修改nslookup
in this post on the hc-dev mailing list的超时时间。
此时我将不得不手动从计时器中抛出超时异常。
【问题讨论】:
请提供您的 Web 服务运行的 IP 地址,而不是域名。我也面临同样的问题。但是我的网络服务在本地机器上运行。所以当我给 localhost 它抛出一个异常。但它接受我的 IP 地址。 【参考方案1】:首先 HttpParams httpParams = new BasicHttpParams() 被贬低, 使用这个 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
当您的参数大小大于 2mb 时,服务器会给出超时响应。
检查您的参数大小并告诉我。
【讨论】:
【参考方案2】:试试这个
public class MyAsync extends AsyncTask<String, Integer, String>
@Override
protected String doInBackground(String... arg0)
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 = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient client=new DefaultHttpClient(httpParameters);
HttpGet get=new HttpGet(arg0[0]);
try
HttpResponse response=client.execute(get);
HttpEntity ent=response.getEntity();
String res=EntityUtils.toString(ent);
Log.d("Nzm", res);
catch (ClientProtocolException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
return null;
【讨论】:
【参考方案3】:DefaultHttpClient client = new DefaultHttpClient();
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 30000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// HttpConnectionParams.setHeader("Accept", "application/json");
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 30000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
client.setParams(httpParameters);
【讨论】:
【参考方案4】:如果您使用线程进行网络操作会更好,然后您可以在外部设置超时。我曾使用此方法解决定义超时不起作用的问题。
在这种方法中,后通信代码被编写在 Handler 中。我们可以通过发送消息来触发这个处理程序(我们也可以通过消息传递数据)。触发语句写在倒数计时器和线程中的通信代码之后。必要的代码被写在处理程序中以禁用更多的触发(通过为对象分配一个新的空处理程序),这样只有一个触发工作。
如果您喜欢这个逻辑并且需要更多解释。请在下方评论
【讨论】:
【参考方案5】:你可以试试这样的:-
URLConnection connection = null;
connection = address.openConnection();
post = (HttpsURLConnection) connection;
post.setSSLSocketFactory(context.getSocketFactory());
post.setDoInput(true);
post.setDoOutput(true);
// Connecting to a server will fail with a SocketTimeoutException if the timeout elapses before a connection is established
post.setConnectTimeout(Const.CONNECTION_TIMEOUT_DELAY);
post.setRequestMethod("POST"); // throws ProtocolException
post.setRequestProperty("soapaction","");
post.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
post.setRequestProperty("Authorization", "Basic " + Base64.encodeToString(strCredentials.getBytes(), Base64.NO_WRAP));
post.setRequestProperty("Content-Length", String.valueOf(requestEnvelope.length()));
//如果在数据可用之前超时,读取将失败并抛出 SocketTimeoutException.. post.setReadTimeout(Const.READ_TIMEOUT_DELAY);
【讨论】:
【参考方案6】:对我来说,如果我们失去连接,则不会使用超时(测试:关闭 WiFi)。所以我写了一个方法,尝试下载文件最多 X 次,每次尝试之间等待 Y 毫秒:
public static byte[] getByteArrayFromURL(String url, int maxTries, int intervalBetweenTries) throws IOException
try
return Utils.getByteArrayFromURL(url);
catch(FileNotFoundException e) throw e;
catch(IOException e)
if(maxTries > 0)
try
Thread.sleep(intervalBetweenTries);
return getByteArrayFromURL(url, maxTries - 1, intervalBetweenTries);
catch (InterruptedException e1)
return getByteArrayFromURL(url, maxTries -1, intervalBetweenTries);
else
throw e;
这是下载文件并抛出 UnknownHostException 的方法:
public static byte[] getByteArrayFromURL(String urlString) throws IOException
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream in = null;
try
in = new URL(urlString).openStream();
byte[] byteChunk = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(byteChunk)) > 0)
out.write(byteChunk, 0, n);
finally
if (in != null)
try in.close();
catch (IOException e) e.printStackTrace();
return out.toByteArray();
现在,如果您要下载的文件不存在,该方法将立即失败,否则如果抛出 IOException(如 UnknownHostException),它将重试,直到“maxTries”,等待“intervalBetweenTries”每次尝试之间。
当然,你必须异步使用它。
【讨论】:
【参考方案7】:我发现 Volley(我会说是 AsyncTask 的替换)库更易于使用,并且错误更少。如果您使用 volley,则更容易管理超时。但是,关于您的问题,
response = httpclient.execute(httpget);
我想你正在使用 AsyncTask。 httpconnection 中也有settimeout()
的选项,但由于DNS 的问题,它不能正常工作。所以尝试使用runnable()
并设置时间。我在我的一个项目中使用了这种方法,早在还没有使用 Volley 的时候。
希望这会有所帮助。
【讨论】:
【参考方案8】:试试这个,也许对你有帮助。
final HttpParams httpParams = new BasicHttpParams()
HttpConnectionParams.setConnectionTimeout(httpParams, 1000)
HttpConnectionParams.setSoTimeout(httpParams, 30000)
HttpClient hc = new DefaultHttpClient(httpParams)
try
HttpGet get = new HttpGet("http://www.google.com")
HttpResponse response = hc.execute(get)
take your response now.
【讨论】:
【参考方案9】:你应该使用这样的东西:
/**
* Check availability of web service
*
* @param host Address of host
* @param seconds Timeout in seconds
* @return Availability of host
*/
public static boolean checkIfURLExists(String host, int seconds)
HttpURLConnection httpUrlConn;
try
httpUrlConn = (HttpURLConnection) new URL(host).openConnection();
// Set timeouts in milliseconds
httpUrlConn.setConnectTimeout(seconds * 1000);
httpUrlConn.setReadTimeout(seconds * 1000);
// Print HTTP status code/message for your information.
System.out.println("Response Code: " + httpUrlConn.getResponseCode());
System.out.println("Response Message: "
+ httpUrlConn.getResponseMessage());
return (httpUrlConn.getResponseCode() == HttpURLConnection.HTTP_OK);
catch (Exception e)
System.out.println("Error: " + e.getMessage());
return false;
【讨论】:
setConnectTimeout 和 setReadTimeout 不适用于 DNS 解析运行时...这就是问题【参考方案10】:请下载此 Jar 文件并导入 lib 文件夹 http://grepcode.com/snapshot/repo1.maven.org/maven2/org.apache.httpcomponents/httpmime/4.2.1 并继续运行您的应用程序..您的代码是正确的
【讨论】:
【参考方案11】:您可以向您的服务器发送 ping 请求并设置 ping 请求的超时时间。如果为真,您有互联网连接,如果为假,则什么也不做。代码应如下所示:
public static boolean connection() throws UnknownHostException, IOException
String ipAddress = "94.103.35.164";
InetAddress inet = InetAddress.getByName(ipAddress);
if(inet.isReachable(1000))
return true;
else
return false;
您可以在此示例中更改您的超时时间。我设置了 1 秒超时。
【讨论】:
【参考方案12】:是的,您可以按照以下步骤设置超时
-
进入eclipse的window->preferences->android->DDMS,增加ADB连接超时时间。
【讨论】:
-1:weakwire 正在谈论他的应用程序中的超时——而不是在 ADB 连接中。以上是关于Android UnknownHostException:有没有办法设置超时?的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )