如何在 Java 中为 Android 设置 HttpResponse 超时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/693997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:25:54  来源:igfitidea点击:

How to set HttpResponse timeout for Android in Java

javaandroidtimeouthttpresponse

提问by Niko Gamulin

I have created the following function for checking the connection status:

我创建了以下函数来检查连接状态:

private void checkConnectionStatus() {
    HttpClient httpClient = new DefaultHttpClient();

    try {
      String url = "http://xxx.xxx.xxx.xxx:8000/GaitLink/"
                   + strSessionString + "/ConnectionStatus";
      Log.d("phobos", "performing get " + url);
      HttpGet method = new HttpGet(new URI(url));
      HttpResponse response = httpClient.execute(method);

      if (response != null) {
        String result = getResponse(response.getEntity());
        ...

When I shut down the server for testing the execution waits a long time at line

当我关闭服务器以测试执行时,排队等候很长时间

HttpResponse response = httpClient.execute(method);

Does anyone know how to set the timeout in order to avoid waiting too long?

有谁知道如何设置超时以避免等待太久?

Thanks!

谢谢!

采纳答案by kuester2000

In my example, two timeouts are set. The connection timeout throws java.net.SocketTimeoutException: Socket is not connectedand the socket timeout java.net.SocketTimeoutException: The operation timed out.

在我的示例中,设置了两个超时。连接超时抛出java.net.SocketTimeoutException: Socket is not connected和套接字超时java.net.SocketTimeoutException: The operation timed out

HttpGet httpGet = new HttpGet(url);
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 = 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);

DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpResponse response = httpClient.execute(httpGet);

If you want to set the Parameters of any existing HTTPClient (e.g. DefaultHttpClient or AndroidHttpClient) you can use the function setParams().

如果您想设置任何现有 HTTPClient(例如 DefaultHttpClient 或 AndroidHttpClient)的参数,您可以使用函数setParams()

httpClient.setParams(httpParameters);

回答by Pablo Santa Cruz

If your are using Jakarta's http client librarythen you can do something like:

如果您使用 Jakarta 的http 客户端库,那么您可以执行以下操作:

        HttpClient client = new HttpClient();
        client.getParams().setParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, new Long(5000));
        client.getParams().setParameter(HttpClientParams.SO_TIMEOUT, new Integer(5000));
        GetMethod method = new GetMethod("http://www.yoururl.com");
        method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(5000));
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
        int statuscode = client.executeMethod(method);

回答by kuester2000

To set settings on the client:

要在客户端上设置设置:

AndroidHttpClient client = AndroidHttpClient.newInstance("Awesome User Agent V/1.0");
HttpConnectionParams.setConnectionTimeout(client.getParams(), 3000);
HttpConnectionParams.setSoTimeout(client.getParams(), 5000);

I've used this successfully on JellyBean, but should also work for older platforms ....

我已经在 J​​ellyBean 上成功使用了它,但也应该适用于旧平台......

HTH

HTH

回答by Sandeep

HttpParams httpParameters = new BasicHttpParams();
            HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(httpParameters,
                    HTTP.DEFAULT_CONTENT_CHARSET);
            HttpProtocolParams.setUseExpectContinue(httpParameters, true);

            // Set the timeout in milliseconds until a connection is
            // established.
            // The default value is zero, that means the timeout is not used.
            int timeoutConnection = 35 * 1000;
            HttpConnectionParams.setConnectionTimeout(httpParameters,
                    timeoutConnection);
            // Set the default socket timeout (SO_TIMEOUT)
            // in milliseconds which is the timeout for waiting for data.
            int timeoutSocket = 30 * 1000;
            HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

回答by Bruno Peres

If you are using the HttpURLConnection, call setConnectTimeout()as described here:

如果您正在使用HttpURLConnection,请setConnectTimeout()按照此处所述进行调用:

URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(CONNECT_TIMEOUT);

回答by foxundermon

you can creat HttpClient instance by the way with Httpclient-android-4.3.5,it can work well.

你可以顺便用Httpclient-android-4.3.5创建HttpClient实例,它可以很好地工作。

 SSLContext sslContext = SSLContexts.createSystemDefault();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext,
                SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
                RequestConfig.Builder requestConfigBuilder = RequestConfig.custom().setCircularRedirectsAllowed(false).setConnectionRequestTimeout(30*1000).setConnectTimeout(30 * 1000).setMaxRedirects(10).setSocketTimeout(60 * 1000);
        CloseableHttpClient hc = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(requestConfigBuilder.build()).build();

回答by Learn OpenGL ES

If you're using the default http client, here's how to do it using the default http params:

如果您使用的是默认 http 客户端,以下是使用默认 http 参数的方法:

HttpClient client = new DefaultHttpClient();
HttpParams params = client.getParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 3000);

Original credit goes to http://www.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/

原始信用转到http://www.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/

回答by David Darias

For those saying that the answer of @kuester2000 does not work, please be aware that HTTP requests, first try to find the host IP with a DNS request and then makes the actual HTTP request to the server, so you may also need to set a timeout for the DNS request.

对于那些说@kuester2000的回答不起作用的人,请注意HTTP请求,首先尝试通过DNS请求找到主机IP,然后向服务器发出实际的HTTP请求,因此您可能还需要设置一个DNS 请求超时。

If your code worked without the timeout for the DNS request it's because you are able to reach a DNS server or you are hitting the Android DNS cache. By the way you can clear this cache by restarting the device.

如果您的代码在没有 DNS 请求超时的情况下工作,那是因为您能够访问 DNS 服务器或者您正在访问 Android DNS 缓存。顺便说一下,您可以通过重新启动设备来清除此缓存。

This code extends the original answer to include a manual DNS lookup with a custom timeout:

此代码扩展了原始答案以包含具有自定义超时的手动 DNS 查找:

//Our objective
String sURL = "http://www.google.com/";
int DNSTimeout = 1000;
int HTTPTimeout = 2000;

//Get the IP of the Host
URL url= null;
try {
     url = ResolveHostIP(sURL,DNSTimeout);
} catch (MalformedURLException e) {
    Log.d("INFO",e.getMessage());
}

if(url==null){
    //the DNS lookup timed out or failed.
}

//Build the request parameters
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, HTTPTimeout);
HttpConnectionParams.setSoTimeout(params, HTTPTimeout);

DefaultHttpClient client = new DefaultHttpClient(params);

HttpResponse httpResponse;
String text;
try {
    //Execute the request (here it blocks the execution until finished or a timeout)
    httpResponse = client.execute(new HttpGet(url.toString()));
} catch (IOException e) {
    //If you hit this probably the connection timed out
    Log.d("INFO",e.getMessage());
}

//If you get here everything went OK so check response code, body or whatever

Used method:

使用方法:

//Run the DNS lookup manually to be able to time it out.
public static URL ResolveHostIP (String sURL, int timeout) throws MalformedURLException {
    URL url= new URL(sURL);
    //Resolve the host IP on a new thread
    DNSResolver dnsRes = new DNSResolver(url.getHost());
    Thread t = new Thread(dnsRes);
    t.start();
    //Join the thread for some time
    try {
        t.join(timeout);
    } catch (InterruptedException e) {
        Log.d("DEBUG", "DNS lookup interrupted");
        return null;
    }

    //get the IP of the host
    InetAddress inetAddr = dnsRes.get();
    if(inetAddr==null) {
        Log.d("DEBUG", "DNS timed out.");
        return null;
    }

    //rebuild the URL with the IP and return it
    Log.d("DEBUG", "DNS solved.");
    return new URL(url.getProtocol(),inetAddr.getHostAddress(),url.getPort(),url.getFile());
}   

This class is from this blog post. Go and check the remarks if you will use it.

这门课来自这篇博文。如果您会使用它,请查看备注。

public static class DNSResolver implements Runnable {
    private String domain;
    private InetAddress inetAddr;

    public DNSResolver(String domain) {
        this.domain = domain;
    }

    public void run() {
        try {
            InetAddress addr = InetAddress.getByName(domain);
            set(addr);
        } catch (UnknownHostException e) {
        }
    }

    public synchronized void set(InetAddress inetAddr) {
        this.inetAddr = inetAddr;
    }
    public synchronized InetAddress get() {
        return inetAddr;
    }
}

回答by androidevil

An option is to use the OkHttpclient, from Square.

一种选择是使用来自 Square的OkHttp客户端。

Add the library dependency

添加库依赖

In the build.gradle, include this line:

在 build.gradle 中,包含以下行:

compile 'com.squareup.okhttp:okhttp:x.x.x'

Where x.x.xis the desired library version.

x.x.x所需的库版本在哪里。

Set the client

设置客户端

For example, if you want to set a timeout of 60 seconds, do this way:

例如,如果要设置 60 秒的超时,请执行以下操作:

final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(60, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(60, TimeUnit.SECONDS);


ps: If your minSdkVersion is greater than 8, you can use TimeUnit.MINUTES. So, you can simply use:

ps:如果你的 minSdkVersion 大于 8,你可以使用TimeUnit.MINUTES. 因此,您可以简单地使用:

okHttpClient.setReadTimeout(1, TimeUnit.MINUTES);
okHttpClient.setConnectTimeout(1, TimeUnit.MINUTES);

For more details about the units, see TimeUnit.

有关单位的更多详细信息,请参阅TimeUnit

回答by Eco4ndly

public boolean isInternetWorking(){
    try {
        int timeOut = 5000;
        Socket socket = new Socket();
        SocketAddress socketAddress = new InetSocketAddress("8.8.8.8",53);
        socket.connect(socketAddress,timeOut);
        socket.close();
        return true;
    } catch (IOException e) {
        //silent
    }
    return false;
}