2010-05-10 12 views
91

यदि URL कनेक्ट करने के लिए 5 सेकंड अधिक लेता है तो मैं झूठी वापसी करना चाहता हूं - यह जावा का उपयोग कैसे संभव है? यहाँ कोड मैं अगर URL वैधHttpURLConnection टाइमआउट सेटिंग्स

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

उत्तर

153

HttpURLConnection एक setConnectTimeout विधि है की जाँच करने के का उपयोग कर रहा है।

बस 5000 मिलीसेकंड के लिए समाप्ति सेट, और फिर पकड़ने java.net.SocketTimeoutException

आपका कोड कुछ इस तरह दिखना चाहिए:

 

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

मैं मान को 10 मिनट तक सेट करता हूं। हालांकि यह मुझे 'java.net' फेंकता है। कनेक्ट अपवाद: कनेक्शन का समय समाप्त हो गया है: 2 मिनट से पहले कनेक्ट करें। क्या आपको पता है कि समस्या का कारण क्या है? – Pacerier

+0

@dbyrne यह मेरे लिए थोड़ा उलझन में प्रतीत होता है - चूंकि हम 'HttpURLConnection' ऑब्जेक्ट के निर्माण के बाद टाइमआउट सेट करते हैं, मुझे आश्चर्य है कि कोड में सही जगह क्या है जो' सॉकेटटाइमआउट अपवाद 'उठाएगी? – Less

+3

सॉकेटटाइमआउट अपवाद IOException का उप-वर्ग है। यदि दोनों पकड़ ब्लॉक एक ही काम करते हैं, तो आप केवल IOException पकड़ सकते हैं। – spaaarky21

85

आप इस तरह टाइमआउट,

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

हम निर्दिष्ट समय सीमा का अधिकतम मूल्य क्या है? – Pacerier

+5

@Pacerier दस्तावेज़ इस स्पष्ट रूप से यह नहीं बताते हैं। यदि मूल्य ऋणात्मक है (0 का मान अनिश्चित काल तक प्रतीक्षा करेगा) तो यह एक अवैध अर्ग्यूमेंट अपवाद को फेंक देता है। चूंकि टाइमआउट एक हस्ताक्षरित 32 बिट इंट है, मुझे लगता है कि अधिकतम टाइमआउट लगभग 49 दिन होगा (हालांकि मुझे गंभीरता से संदेह है कि इस तरह का मूल्य किसी के लिए सहायक होगा)। कई प्रकार के टाइमआउट के लिए –

+1

+1 ... – jsh

1

तो सेट कर सकते हैं HTTP कनेक्शन टाइमआउट नहीं करता है, आप बैकग्राउंड थ्रेड में ही टाइमआउट चेकर को लागू कर सकते हैं (AsyncTask, Service, आदि), निम्न श्रेणी एक परीक्षा है अनुकूलित AsyncTask के लिए मिसाल है जो निश्चित अवधि के

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

इस

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

कॉल करने के लिए बस एक नया लूपर थ्रेड बनाने के लिए बिल्कुल अनावश्यक है रद्द करना()। आप इसे मुख्य थ्रेड से 'onPreExecute()' में कर सकते हैं।साथ ही, यदि आप मैन्युअल रूप से कार्य को रद्द करते हैं, तो आपको लीक से बचने के लिए निर्धारित कॉल को भी रद्द करना चाहिए। – BladeCoder

+0

यहां इंगित करें doInBackground() के मध्य में AsyncTask को रद्द करना है जब निष्पादन पर बहुत अधिक समय लगता है, PreExecute() पर भी, मैं भी AsyncTask के इस उदाहरण को रद्द करना चाहता हूं जो बहुत अधिक समय लेता है और दूसरों को बहुत अधिक रखता है आपकी प्रतिपुष्टि की सराहना। –

+1

मुझे लगता है कि मेरा संदेश पर्याप्त स्पष्ट नहीं था। मैंने यह नहीं कहा कि आपको PreExecute() पर रद्द करना चाहिए, मैंने कहा है कि आपको हैंडलर को ऑनपेक्सक्यूट() में बनाना चाहिए और मुख्य थ्रेड से देरी रद्द करना पोस्ट करना चाहिए। इस तरह आप मुख्य धागे को लूपर थ्रेड के रूप में उपयोग करेंगे और आप निश्चित रूप से AsyncTask को रद्द कर सकते हैं जबकि doInBackground() निष्पादित हो रहा है क्योंकि मुख्य थ्रेड पृष्ठभूमि थ्रेड के साथ समवर्ती रूप से चलता है। – BladeCoder

0

के लिए एक नमूना मैं एक सरल रेखा

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

के योग के साथ इस तरह के एक समान समस्या के लिए समाधान मिल सकता है के बाद समय समाप्त मेरे प्रतिक्रिया कोड को जानना था और इसके लिए पूर्ण प्रतिक्रिया निकाय निकालने के बजाय मेटा-सूचना प्राप्त करना पर्याप्त था।

डिफ़ॉल्ट अनुरोध विधि प्राप्त होती है और उसे वापस करने के लिए बहुत समय लग रहा था, अंततः मुझे सॉकेटटाइमआउट अपवाद फेंक रहा था। जब मैं अनुरोध विधि को हेड सेट करता हूं तो प्रतिक्रिया बहुत तेज थी।

संबंधित मुद्दे