Android UnknownHostException:有没有办法设置超时?

时间:2012-03-08 23:35:02

标签: java android httpclient

当我连接到我的网络服务以检索数据时,手机有时会断开连接,DNS搞砸了等等。然后我得到一个UnknownHostException,这完全没问题。

我想要做的是在这里查找hostName时设置超时:

 response = httpclient.execute(httpget);

我已经设定了:

HttpConnectionParams.setConnectionTimeout(httpParameters,timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

但它们似乎不适用于HostLookUp。有没有办法在主机查找时设置超时?

修改
我刚发现用户无法修改nslookup in this post on the hc-dev mailing list的暂停时间。

我将不得不在此时从计时器手动抛出超时异常。

12 个答案:

答案 0 :(得分:2)

首先,HttpParams httpParams = new BasicHttpParams()被删除, 使用此HttpURLConnection conn =(HttpURLConnection)url.openConnection();

当参数大小超过2mb时,服务器会给出超时响应。

检查你的参数大小并告诉我。

答案 1 :(得分:0)

试试这个

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;
}

}

答案 2 :(得分:0)

我发现Volley(我会说更换AsyncTask)库更容易使用,也可以减少错误。如果使用排球,则更容易管理超时。但是,关于你的问题,

  response = httpclient.execute(httpget);

有了这个,我猜你正在使用AsyncTask。 httpconnection中还有settimeout()选项,但由于DNS存在问题而无法正常工作。因此,请尝试使用runnable()和settime。我在我的一个项目中使用过这种方法,当时还没有使用Volley。

希望这会有所帮助。

答案 3 :(得分:0)

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 :(得分:0)

如果你使用线程进行网络操作会更好,那么你可以在外部给出一个超时。我已经用这个方法来解决定义超时不起作用的问题。

在此方法中,后通信代码写入处理程序。我们可以通过发送消息来触发这个处理程序(我们也可以通过消息传递数据)。触发语句写入倒计时器和线程中的通信代码之后。必要的代码写入处理程序以禁用任何触发(通过为对象分配新的空处理程序)使得只有一个触发工作。

如果您喜欢这种逻辑并需要更多解释。请在下面评论

答案 5 :(得分:0)

您可以尝试以下方式: -

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 :(得分:0)

对我来说,如果我们丢失连接(测试:关闭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 :(得分:0)

  

试试这个,可能会对你有所帮助。

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.

}

答案 8 :(得分:-1)

你应该使用这样的东西:

/**
 * 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;
    }
}

答案 9 :(得分:-1)

请下载此Jar文件并导入到lib文件夹http://grepcode.com/snapshot/repo1.maven.org/maven2/org.apache.httpcomponents/httpmime/4.2.1并继续运行您的应用程序..您的代码是否正确

答案 10 :(得分:-2)

是的,您可以按照以下步骤设置超时

  1. 转到eclipse的窗口 - &gt; preferences-&gt; Android-&gt; DDMS并增加ADB连接时间。

答案 11 :(得分:-2)

您可以向服务器发送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秒超时。