337 Stimmen

Festlegen der HttpResponse-Zeitüberschreitung für Android in Java

Ich habe die folgende Funktion zur Überprüfung des Verbindungsstatus erstellt:

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());
        ...

Wenn ich den Server zu Testzwecken herunterfahre, wartet die Ausführung sehr lange in der Zeile

HttpResponse response = httpClient.execute(method);

Weiß jemand, wie man die Zeitüberschreitung einstellen kann, um zu lange Wartezeiten zu vermeiden?

Danke!

625voto

kuester2000 Punkte 6957

In meinem Beispiel werden zwei Timeouts gesetzt. Die Zeitüberschreitung der Verbindung führt zu java.net.SocketTimeoutException: Socket is not connected und die Socket-Zeitüberschreitung 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);

Wenn Sie die Parameter eines vorhandenen HTTPClient (z.B. DefaultHttpClient oder AndroidHttpClient) setzen wollen, können Sie die Funktion setParams() .

httpClient.setParams(httpParameters);

13voto

Um Einstellungen auf dem Client vorzunehmen:

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

Ich habe dies erfolgreich auf JellyBean verwendet, sollte aber auch für ältere Plattformen funktionieren ....

HTH

8voto

Pablo Santa Cruz Punkte 169147

Wenn Sie Jakartas http-Client-Bibliothek dann können Sie etwas tun wie:

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

7voto

Learn OpenGL ES Punkte 4468

Wenn Sie den Standard-HTTP-Client verwenden, finden Sie hier eine Anleitung zur Verwendung der Standard-HTTP-Parameter:

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

Der ursprüngliche Kredit geht an http://www.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/

5voto

David Darias Punkte 520

Für diejenigen, die sagen, dass die Antwort von @kuester2000 nicht funktioniert, sei darauf hingewiesen, dass HTTP-Anfragen zuerst versuchen, die Host-IP mit einer DNS-Anfrage zu finden, und dann die eigentliche HTTP-Anfrage an den Server stellen, so dass Sie möglicherweise auch ein Timeout für die DNS-Anfrage einstellen müssen.

Wenn Ihr Code ohne die Zeitüberschreitung für die DNS-Anfrage funktioniert hat, liegt das daran, dass Sie einen DNS-Server erreichen können oder dass Sie auf den DNS-Cache von Android treffen. Übrigens können Sie diesen Cache durch einen Neustart des Geräts löschen.

Dieser Code erweitert die ursprüngliche Antwort um einen manuellen DNS-Lookup mit einem benutzerdefinierten Timeout:

//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

Verwendete Methode:

//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());
}   

Diese Klasse ist von dieser Blogbeitrag . Überprüfen Sie die Bemerkungen, wenn Sie sie verwenden wollen.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X