2010-05-10 24 views
91

URL daha sonra 5 saniye sürüyorsa false döndürmek istiyorum - Java ile bu nasıl mümkündür? İşte URLHttpURLConnection timeout ayarları

HttpURLConnection.setFollowRedirects(false); 
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(); 
con.setRequestMethod("HEAD"); 
return (con.getResponseCode() == HttpURLConnection.HTTP_OK); 

cevap

153

HttpURLConnection bir setConnectTimeout yöntemi vardır geçerli olup olmadığını kontrol etmek için kullanıyorum kodudur.

Sadece 5000 milisaniye için zaman aşımı ayarlamak ve sonra yakalamak java.net.SocketTimeoutException

böyle bir şey görünmelidir kodu:

 

try { 
    HttpURLConnection.setFollowRedirects(false); 
    HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(); 
    con.setRequestMethod("HEAD"); 

    con.setConnectTimeout(5000); //set timeout to 5 seconds 

    return (con.getResponseCode() == HttpURLConnection.HTTP_OK); 
} catch (java.net.SocketTimeoutException e) { 
    return false; 
} catch (java.io.IOException e) { 
    return false; 
} 

 
+1

Değeri 10 dakikaya ayarlıyorum. Ancak bana bir java.net.ConnectException atar: Bağlantı zaman aşımına uğradı: connect 'önce bile 2 dakika doldu. Soruna neyin neden olduğunu biliyor musun? – Pacerier

+0

@dbyrne bana biraz kafa karıştırıcı geliyor - HttpURLConnection nesnesi oluşturulduktan sonra zaman aşımını ayarladığımızdan beri, kodda SocketTimeoutException öğesini yükseltecek olan yerin tam olarak ne olduğunu merak ediyorum. – Less

+3

SocketTimeoutException, IOException'ın bir alt sınıfıdır. Her iki yakalama bloğu da aynı şeyi yaparsa, IOException'ı yakalayabilirsiniz. – spaaarky21

85

Böyle zaman aşımı,

con.setConnectTimeout(connectTimeout); 
con.setReadTimeout(socketTimeout); 
+1

Belirleyebileceğimiz zaman aşımının maksimum değeri nedir? – Pacerier

+5

@Pacerier Dokümanlar bunu açıkça belirtmez. Değer negatifse, bir IllegalArgumentException atar (0 değeri, sonsuza kadar beklemek anlamına gelir). Zaman aşımı imzasız bir 32bit int olduğundan, max zaman aşımının yaklaşık 49 gün olacağını tahmin ediyorum (bu tür bir değerin kimseye yararlı olduğundan şüphe etmeme rağmen). –

+1

+1 birden fazla zaman aşımı türü için ... – jsh

1

Eğer ayarlayabilirsiniz HTTP Bağlantısı zaman aşımına uğramaz, Zamanaşımı denetleyicisini arka plan iş parçacığının kendisinde uygulayabilirsiniz (AsyncTask, Service, vb.), aşağıdaki sınıf bir sınavdır. belirli bir süre

public abstract class AsyncTaskWithTimer<Params, Progress, Result> extends 
    AsyncTask<Params, Progress, Result> { 

private static final int HTTP_REQUEST_TIMEOUT = 30000; 

@Override 
protected Result doInBackground(Params... params) { 
    createTimeoutListener(); 
    return doInBackgroundImpl(params); 
} 

private void createTimeoutListener() { 
    Thread timeout = new Thread() { 
     public void run() { 
      Looper.prepare(); 

      final Handler handler = new Handler(); 
      handler.postDelayed(new Runnable() { 
       @Override 
       public void run() { 

        if (AsyncTaskWithTimer.this != null 
          && AsyncTaskWithTimer.this.getStatus() != Status.FINISHED) 
         AsyncTaskWithTimer.this.cancel(true); 
        handler.removeCallbacks(this); 
        Looper.myLooper().quit(); 
       } 
      }, HTTP_REQUEST_TIMEOUT); 

      Looper.loop(); 
     } 
    }; 
    timeout.start(); 
} 

abstract protected Result doInBackgroundImpl(Params... params); 
} 

Basit çizgi

HttpURLConnection hConn = (HttpURLConnection) url.openConnection(); 
hConn.setRequestMethod("HEAD"); 

eklenmesiyle böyle benzer bir sorun için bir çözüm alabilir bu

public class AsyncTaskWithTimerSample extends AsyncTaskWithTimer<Void, Void, Void> { 

    @Override 
    protected void onCancelled(Void void) { 
     Log.d(TAG, "Async Task onCancelled With Result"); 
     super.onCancelled(result); 
    } 

    @Override 
    protected void onCancelled() { 
     Log.d(TAG, "Async Task onCancelled"); 
     super.onCancelled(); 
    } 

    @Override 
    protected Void doInBackgroundImpl(Void... params) { 
     // Do background work 
     return null; 
    }; 
} 
+0

Sadece bir çağrı planlamak için yeni bir lüper iplik oluşturmak için kesinlikle gereksizdir iptal etmek(). Bunu onPreExecute() 'deki ana iş parçacığından yapabilirsiniz.Ayrıca, görevi el ile iptal ederseniz, sızıntıları önlemek için programlanmış çağrıyı da iptal etmelisiniz. – BladeCoder

+0

Burada, doInBackground() öğesinin orIndaki AsyncTask öğesinin, onPreExecute() öğesinde yürütme sırasında çok fazla zaman alması durumunda iptal edilmesi gerekiyor. Ayrıca, çok fazla zaman alan ve diğerlerini saklayan AsyncTask'ın yalnızca bu örneğini iptal etmek istiyorum dönüşünüz için minnettarız. –

+1

Sanırım mesajım yeterince açık değildi. OnPreExecute() 'da iptal etmeniz gerektiğini söylemedim, HandPart'ı onPreExecute()' da oluşturmalı ve ana konuyu gecikmeli iptal etmelisiniz. Bu şekilde, ana iş parçacığını lüper iş parçacığı olarak kullanacaksınız ve tabii ki AsyncTask'ı daha sonra iptal edebilirsiniz, çünkü ana iş parçacığı aynı zamanda arka plan iş parçacığı ile aynı anda çalıştığı için doInBackground() çalıştırılıyor. – BladeCoder

0

için bir örnek sonra özelleştir AsyncTask için ple hangi zaman aşımı Benim Gereksinim cevap kodunu tanımaktı ve bunun için tam cevap gövdesini almak yerine sadece meta-bilginin yeterli olması gerekiyordu.

Varsayılan istek yöntemi GET'tir ve bu geri dönmek için çok zaman harcıyordu, nihayet SocketTimeoutException. İstek Metodu'nu HEAD olarak ayarladığımda yanıt oldukça hızlıydı.