2012-07-04 11 views
14

मैं निम्नलिखित कोड ब्लॉक है:एंड्रॉइड HttpURLConnection द्वारा टाइमआउट मान का सम्मान क्यों नहीं किया जाता है?

try { 
    URL url = new URL("http://site-to-test.com/nonexistingpage.html"); 

    HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); 
    urlc.setRequestProperty("User-Agent", CoreProtocolPNames.USER_AGENT); 
    urlc.setRequestProperty("Connection", "close"); 
    urlc.setConnectTimeout(500); // timeout is in milliseconds 
    urlc.connect(); 

    if (urlc.getResponseCode() == 404) { 
     // Server was reachable 
     Log.i(TAG, "Server is reachable"); 
    } 

} catch (MalformedURLException mue) { 
    Log.e(TAG, "MalformedURLException: " + mue.getMessage()); 
} catch (IOException e) { 
    Log.e(TAG, "IOException: " + e.getMessage()); 
} 

जब site-to-test डोमेन वर्तमान नेटवर्क के माध्यम से पहुंच योग्य नहीं है, IOException प्राप्त करने से पहले 30-40 के बारे में सेकंड के लिए इस कोड ब्लॉक। और मैं विशेष रूप से टाइमआउट मान 500ms पर सेट करता हूं। मुझे यहां क्या समझ नहीं आ रहा है? नेटवर्क स्थिति और साइट की उपलब्धता के बावजूद उपरोक्त ब्लॉक आधे सेकेंड में समाप्त नहीं होना चाहिए?

+1

आप Timertask उपयोग कर सकते हैं और के लिए एक नमूना अपने HTTP कनेक्शन के लिए समय समाप्त की जांच की जरूरत है कार्यान्वित सीमा निर्धारित करने के लिए टाइमर एक साथ .... –

+0

बीटीडब्ल्यू, आप इसे एक अलग 'थ्रेड' (या 'AsyncTask') पर कर रहे हैं, है ना? –

+0

हां, एलेक्स, मैं यूआई थ्रेड को अवरुद्ध करने का सपना नहीं देखूंगा। –

उत्तर

13

ऐसा प्रतीत होता है Java URLConnection provides no fail-safe timeout on reads

कि समाधान है, जैसा कि लेख बताते हैं, समय के लिए एक अलग थ्रेड का उपयोग करने, और मैन्युअल रूप से HttpURLConnection डिस्कनेक्ट एक बार टाइमर धागा किया जाता है।

+0

क्या यह कार्य संभव है यदि मैं थ्रेड के बजाय AsyncTask का उपयोग करता हूं? – NoBugs

+0

मुझे लगता है कि मुझे एंड्रॉइड में मेरी AsyncTask समस्या के लिए एक अच्छा समाधान मिला है। मैंने एक निश्चित देरी के बाद इसे रोकने के लिए टाइमर सेट किया है, और टाइमर को रीसेट कर दिया है जब यह एक और टुकड़ा डाउनलोड करता है। इस तरह यह धीमी कनेक्शन पर समय नहीं निकालता है, लेकिन नेटवर्क डिस्कनेक्ट होने पर समय समाप्त हो जाता है: http://stackoverflow.com/questions/6829801/httpurlconnection-setconnecttimeout-has-no-effect/11790633#11790633 – NoBugs

+0

मेरे पास ' HttpURLConnection' ऑब्जेक्ट, डेटा प्राप्त करें और इसे 'आउटपुटस्ट्रीम' ऑब्जेक्ट का उपयोग करके फ़ाइल में लिखने का प्रयास करें। 'output = connection.getOutputStream();'। वाई-फाई बंद करने के बाद, 'कनेक्टएक्सप्शन' फेंक दिया गया था। क्या इसका मतलब है कि मैं अपने नेटवर्क कनेक्शन को सुन सकता हूं? –

1

गहरी जांच और बहुत सारे ट्रेल्स के बाद, मैंने पाया कि असीन्टास्क (या सेवा, ऑब्जेक्ट जो आप पृष्ठभूमि कार्य करने के लिए प्रयुक्त ऑब्जेक्ट) के लिए टाइमर को लागू करने का सबसे अच्छा तरीका HTTP कनेक्शन क्लास से दूर करते हैं, कभी-कभी जब आप डिस्कनेक्ट करते हैं HTTP कनेक्शन, इस वेब कॉल बीच में नहीं है, मैं इस वर्ग के लिए इस्तेमाल किया जा करने के लिए जब आप

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

महान काम करता है। धन्यवाद। SetXXXTimeout विधियों का सम्मान करने के लिए मेरे जीवन के लिए HttpURLConnection नहीं मिल सका। –