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

asc*_*scu 42 post android timeout http

我正在写一个连接到Web服务应用程序,我不希望它等待太久,如果它不能得到一个连接.因此,我设置了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();
}
Run Code Online (Sandbox Code Playgroud)

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

Cri*_*ian 74

尝试这样做:

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;
Run Code Online (Sandbox Code Playgroud)

然后你可以抓住一个可能的ConnectTimeoutException.

  • 系统如何通知超时以及要处理的异常? (3认同)
  • 30秒后我仍然收到UnknownHostException.在这种情况下,设备连接到wifi路由器,但没有互联网访问.任何线索如何使这个调用处理?否则我可能会回到外部计时器...... :( (3认同)

hoo*_*dfx 9

使用标记的解决方案,我在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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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

    if(!resolveDns()){
        return null;
    }
Run Code Online (Sandbox Code Playgroud)


Jr.*_*Jr. 1

这个方法对我有用:

AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;
Run Code Online (Sandbox Code Playgroud)