2012-03-08 22 views
27

Po połączeniu się z moją usługą internetową w celu odzyskania danych, telefon czasami się rozłącza, DNS zawodzi, itd. Wtedy dostaję UnknownHostException, co jest całkowicie w porządku.Android UnknownHostException: czy istnieje sposób na ustawienie limitu czasu?

Co chcę zrobić, to ustawić limit czasu przy poszukiwaniu hostName tutaj:

response = httpclient.execute(httpget); 

już ustawiony:

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

ale oni nie wydają się ubiegać HostLookUp . Czy jest jakiś sposób ustawić limit czasu na wyszukiwanie hosta?

Edit
Właśnie okazało się, że użytkownik nie może modyfikować timeout nslookupin this post on the hc-dev mailing list.

Będę musiał ręcznie wyrzucić wyjątek limitu czasu z licznika czasu w tym punkcie.

+0

Podaj adres IP, na którym działa twoja usługa internetowa zamiast nazwy domeny. Zmierzyłem się również z tym samym problemem. Ale moja usługa internetowa działa lokalnie na moim komputerze. Więc podczas gdy ja daje mi localhost, rzuca wyjątek. Ale akceptuje mój adres IP. –

Odpowiedz

-1

Należy używać coś takiego:

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

setConnectTimeout i setReadTimeout nie mają zastosowania do środowiska wykonawczego do rozpoznawania nazw DNS ... to jest problem – weakwire

0

Spróbuj

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

tak możesz ustawić limit czasu po tym krok

  1. przejdź do okna zaćmienia-> preferencje-> Android-> DDMS i wydłuż czas połączenia ADB.
+2

-1: weakwire mówi o limicie czasu w swojej aplikacji - nie w połączeniu ADB. – sven

-2

Możesz wysłać żądanie ping do swojego serwera i ustawić limit czasu dla żądania ping. Jeśli prawda, masz połączenie z Internetem, jeśli fałsz nie rób nic. Kod powinien wyglądać następująco:

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

Można zmienić czas w tym przykładzie. Ustawiłem 1 sekundowy limit czasu.

+0

dlaczego edytowałeś moją odpowiedź pustymi spacjami =)) – Shockelduck

0

znajdę Volley (powiedziałbym wymiana AsyncTask) biblioteki jest łatwiejszy w użyciu, a także daje mniej błędów. Jeśli użyjesz salwy, łatwiej będzie zarządzać limitami czasu. Jednak chodzi o Twoje pytanie,

response = httpclient.execute(httpget); 

z tym mam używanego AsyncTask. Istnieje również opcja settimeout() w połączeniu http, ale to nie działa poprawnie z powodu problemu z serwerem DNS. Więc spróbuj użyć runnable() i ustal do niego. Użyłem tego podejścia w jednym z moich projektów, kiedy nie używam jeszcze Volley.

Mam nadzieję, że to pomoże.

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

Będzie lepiej, jeśli używasz wątków dla operacji sieciowych następnie można dać timeout externally.I użył tej metody, aby rozwiązać problem polegający na określeniu limitu czasu nie działa.

W tej metodzie kody połączeń pocztowych są zapisywane w module obsługi. Możemy uruchomić ten moduł obsługi, wysyłając wiadomość (możemy również przekazywać dane za pośrednictwem wiadomości). Wywołania wyzwalające są zapisywane w liczniku odliczającym i po kodach komunikacyjnych w wątku. Niezbędny kod jest zapisywany w programie obsługi w celu wyłączenia wyzwalania (poprzez przypisanie nowego obiektu pustego do obiektu) Tak, aby tylko jedna z operacji wyzwalania działała.

Jeśli podoba ci się ta logika i wymaga więcej wyjaśnień. Proszę o komentarz poniżej

0

Można spróbować czegoś takiego: -

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

// Odczyt zakończy się niepowodzeniem z SocketTimeoutException jeśli limit czasu upłynie zanim dane będą dostępne .. post.setReadTimeout (Const.READ_TIMEOUT_DELAY);

0

Dla mnie timeout nie był używany, jeśli utraciliśmy połączenie (aby przetestować: wyłączyć WiFi). Napisałem więc metodę, która próbuje pobrać plik do x razy, czekając milisekund Y między sobą spróbować:

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

Oto metoda, która pobrać plik i rzuca 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(); 
} 

Teraz, jeśli plik, który chcesz pobrać, nie istnieje, metoda natychmiast się nie powiedzie, w przeciwnym razie, jeśli zostanie zgłoszony wyjątek IOException (jak wyjątek UnknownHostException), spróbuje ponownie, aż do "maxTries", czekając "intervalBetweenTries" pomiędzy każdą próbą .

Oczywiście należy użyć tego asynchronicznie.

0

Wypróbuj tę, może być pomocna.

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. 

}

2

Przede wszystkim HttpParams httpParams = nowych BasicHttpParams() jest depricated, użycia tej HttpURLConnection Conn = (HttpURLConnection url.openConnection)();

, gdy parametry mają rozmiar większy niż 2mb, serwer udziela odpowiedzi czasowej.

Sprawdź rozmiar swoich params i daj mi znać.

Powiązane problemy