android defaluthttpclient timeout 整理
android defaulthttpclient 超时无效的相关解放方式记录:
With the marked solution I am still getting a UnknownHostException after 30+ seconds. In this case the device is connected to a wifi router but there is no internet access.
The approach taken was to kick off an AsyncTask that will just attempt to resolve the hostname. The blocking call checks every 250 ms to see if it succeeded, and after 4 seconds it will cancel the task and return.
This is what I did to solve it:
private boolean dnsOkay = false; private static final int DNS_SLEEP_WAIT = 250; private synchronized boolean resolveDns(){ RemoteDnsCheck check = new RemoteDnsCheck(); check.execute(); try { int timeSlept = 0; while(!dnsOkay && timeSlept<4000){ //Log.d("RemoteDnsCheck", "sleeping"); Thread.sleep(DNS_SLEEP_WAIT); timeSlept+=DNS_SLEEP_WAIT; //Log.d("RemoteDnsCheck", "slept"); } } catch (InterruptedException e) { } if(!dnsOkay){ Log.d("resolveDns", "cancelling"); check.cancel(true); Log.d("resolveDns", "cancelled"); } return dnsOkay; } private class RemoteDnsCheck extends AsyncTask<Void, Void, Void>{ @Override protected Void doInBackground(Void... params) { try { Log.d("RemoteDnsCheck", "starting"); dnsOkay = false; InetAddress addr = InetAddress.getByName(baseServiceURL); if(addr!=null){ Log.d("RemoteDnsCheck", "got addr"); dnsOkay = true; } } catch (UnknownHostException e) { Log.d("RemoteDnsCheck", "UnknownHostException"); } return null; } }
Then, any time I want to do a web call, this is called at the beginning of the function:
if(!resolveDns()){ return null; }- This method works for me :
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;
3.
Thread t=new Thread() { public void run() { try { Thread.sleep(absolutetimeout); httpclient.getConnectionManager().closeExpiredConnections(); httpclient.getConnectionManager().closeIdleConnections(absolutetimeout,TimeUnit.MILLISECONDS); httpclient.getConnectionManager().shutdown(); log.debug("We shutdown the connection manager!"); } catch(InterruptedException e) {} } }; t.start(); HttpResponse res= httpclient.execute(httpget); t.interrupt();
Is that along the lines of what you all are suggesting?
I'm not exactly sure how to cancel the execute once it has started, but this seemed to work for me. I'm not sure which of the three lines in the thread did the magic, or if it was some combination of all of them.
The problem might be in the Apache HTTP Client. See HTTPCLIENT-1098. Fixed in 4.1.2.
The timeout exception tries to reverse DNS the IP, for logging purposes. This takes an additional time until the exception is actually fired.
How are you making the HTTP Connection? This looks like a threading issue. If you are using a background thread, then the thread may be killed along with any timeout registered. The fact that it works the next time tells me that your code will work, if you make the call in a android component and manage the WAKE_LOCK on it yourself. Anyways please post more information about the calling mechanism?