17

当我尝试使用连接到 url 的 HttpClient 时遇到问题。即使我设置了连接超时,http 连接也需要更长的时间才能超时。

int timeoutConnection = 5000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);

int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

它在大多数情况下都能完美运行。但是,每隔一段时间,http 连接就会永远运行并忽略setconnectiontimeout,尤其是当手机连接到 wifi 并且手机处于空闲状态时。

所以在手机空闲后,我第一次尝试连接时,http连接会忽略setconnectiontimeout并永远运行,在我取消它并重试之后,它每次都像魅力一样工作。但是那一次不起作用它会产生一个threadtimeout错误,我尝试使用不同的线程,它可以工作,但我知道该线程运行了很长时间。

我知道 wifi 在空闲时进入睡眠状态,但我不明白为什么它忽略了setconnectiontimeout.

任何人都可以提供帮助,我真的很感激。

4

10 回答 10

9

不确定这是否对您有帮助,但我认为值得在这里分享。在玩超时的东西时,我发现您可以分配第三种超时类型:

// the timeout until a connection is established
private static final int CONNECTION_TIMEOUT = 5000; /* 5 seconds */

// the timeout for waiting for data
private static final int SOCKET_TIMEOUT = 5000; /* 5 seconds */

// ----------- this is the one I am talking about:
// the timeout until a ManagedClientConnection is got 
// from ClientConnectionRequest
private static final long MCC_TIMEOUT = 5000; /* 5 seconds */

...

HttpGet httpGet = new HttpGet(url);
setTimeouts(httpGet.getParams());

...

private static void setTimeouts(HttpParams params) {
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 
        CONNECTION_TIMEOUT);
    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SOCKET_TIMEOUT);
    params.setLongParameter(ConnManagerPNames.TIMEOUT, MCC_TIMEOUT);
}
于 2011-01-02T11:50:34.403 回答
1
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();

这是否符合你们所有人的建议?

我不确定如何在执行开始后取消执行,但这似乎对我有用。我不确定线程​​中的三行中的哪一行发挥了魔力,或者它是否是所有这些行的某种组合。

于 2011-03-31T18:38:06.237 回答
1

我遇到了同样的问题,我猜可能Android不支持这个参数。就我而言,我测试了 ThreadSafeClientConnManager 的所有三个参数

params.setParameter( ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(20) );
params.setIntParameter( ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 200 );
params.setLongParameter( ConnManagerPNames.TIMEOUT, 10 );
ThreadSafeClientConnManager connmgr = new ThreadSafeClientConnManager( params );

第一个和第二个工作正常,但第三个没有按记录工作。当 DefaultHttpClient#execute() 正在执行时,没有抛出异常并且正在执行的线程被无限期地阻塞。

参见http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e650
"...可以通过设置'http. conn-manager.timeout' 为正值。如果在给定的时间段内无法处理连接请求,将抛出 ConnectionPoolTimeoutException。”

于 2011-05-21T08:17:22.647 回答
0

虽然我没有在 Android 平台上看到过这种情况,但我在其他平台上也看到过类似的情况,在这些情况下的解决方案是自己管理超时。当您提出请求时,启动另一个线程(超时线程)。超时线程倒计时所需时间。如果超时在您收到任何数据之前到期,超时线程将取消原始请求,然后您重试新请求。更难编码,但至少你知道它会起作用。

于 2011-01-18T16:10:43.627 回答
0

您可以自己管理超时,这样您就可以确信无论连接处于何种状态,除非您收到可接受的响应,否则您的超时将触发并且 http 请求将被中止。

于 2011-01-02T09:37:58.430 回答
0

好吧,如果您空闲/多任务到另一个应用程序,那么您正在运行的线程可能会被停止和销毁。也许您应该将连接代码放在 Service 中?:

http://developer.android.com/reference/android/os/AsyncTask.html http://developer.android.com/reference/android/app/IntentService.html

于 2011-01-21T17:52:55.760 回答
0

我在android上遇到了类似的超时问题。为了解决这个问题,我在尝试建立连接以及对连接进行任何读取或写入操作时使用了命令不要让手机空闲。在这种情况下,它可能也值得一试。

于 2011-01-12T14:28:41.190 回答
0

你是如何建立 HTTP 连接的?这看起来像一个线程问题。如果您使用的是后台线程,则该线程可能会与注册的任何超时一起被终止。它下次工作的事实告诉我,如果你在一个 android 组件中进行调用并自己管理它的 WAKE_LOCK,你的代码将工作。无论如何,请发布有关调用机制的更多信息?

于 2011-01-21T18:02:49.640 回答
0

从您的片段来看,如果您在调用之前设置超时,最终并不清楚HttpClient.executeMethod(..)。所以这是我的猜测。

于 2011-01-19T19:48:08.877 回答
0

问题可能出在 Apache HTTP 客户端中。请参阅HTTPCLIENT-1098。在 4.1.2 中修复。

超时异常尝试反转 DNS IP,以进行日志记录。这需要额外的时间才能真正触发异常。

于 2013-11-17T13:16:49.230 回答