首页 文章

Android上的Http连接超时无法正常工作

提问于
浏览
42

我正在编写一个连接到Web服务的应用程序,如果它无法 Build 连接,我不希望它等待太久 . 因此,我设置了httpparams的connectionTimeout . 但它似乎没有任何影响 .

测试我暂时关闭我的WLAN . 应用程序尝试连接相当长的时间(超过我想要的3秒),然后抛出UnknownHostException .

这是我的代码:

try{
    HttpClient httpclient = new DefaultHttpClient();
    HttpParams params = httpclient.getParams();
    HttpConnectionParams.setConnectionTimeout(params, 3000);
    HttpConnectionParams.setSoTimeout(params, 3000);

    httppost = new HttpPost(URL);
    StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
    httppost.setEntity(se);
    //Code stops here until UnknownHostException is thrown.
    BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient.execute(httppost);

    HttpEntity entity = httpResponse.getEntity();
    return entity;

}catch (Exception e){
    e.printStackTrace();
}

任何人都有我想念的想法吗?

5 回答

  • 3

    尝试这样做:

    HttpPost httpPost = new HttpPost(url);
    StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
    httpPost.setEntity(se);
    
    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 = 3000;
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
    
    DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
    BasicHttpResponse httpResponse = (BasicHttpResponse)  httpClient.execute(httpPost);
    
    HttpEntity entity = httpResponse.getEntity();
    return entity;
    

    然后你可以 grab 一个可能ConnectTimeoutException .

  • 1

    使用标记的解决方案,我仍然在30秒后收到UnknownHostException . 在这种情况下,设备连接到wifi路由器,但没有互联网访问 .

    采取的方法是启动一个只会尝试解析主机名的AsyncTask . 阻塞调用每250毫秒检查一次是否成功,4秒后它将取消该任务并返回 .

    这就是我解决它的方法:

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

    然后,每当我想要进行Web调用时,都会在函数开头调用它:

    if(!resolveDns()){
            return null;
        }
    
  • 0

    见:https://stackoverflow.com/a/20031077/2609238

    问题可能出在Apache HTTP Client中 . 请参阅HTTPCLIENT-1098 . 在4.1.2中修复 .

    超时异常尝试将DNS反转为IP,以进行日志记录 . 这需要额外的时间,直到实际触发异常 .

  • 74

    这个方法适合我:

    AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;
    
  • 9
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
    // Set the default socket timeout (SO_TIMEOUT)
    

相关问题