从WiFi连接切换到3G会导致连接挂起?

3
我有一个应用程序连接到一个 web 服务。只要在应用程序生命周期内保持连接类型的一致性,使用 WIFI 或 3G 都可以无限次数地连接到 web 服务而不会出现任何问题。也就是说,如果我没有从 WIFI 切换到 3G,则没有问题。但如果我从 WIFI 切换到 3G,就再也收不到响应了。我的连接一直在等待响应。
我尝试了以下 4 种情况。只有第三种情况出现了问题。这可能是什么原因呢?
1. 连接始终使用 WIFI(正常) 1. 应用程序使用 WIFI 连接到 web 服务。 2. 成功接收到响应。 3. 应用程序再次使用 WIFI 连接到 web 服务。 4. 成功接收到响应。
2. 连接始终使用 3G(正常) 1. 应用程序使用 WIFI 连接到 web 服务。 2. 成功接收到响应。 3. 应用程序再次使用 WIFI 连接到 web 服务。 4. 成功接收到响应。
3. 连接从 WIFI 切换到 3G(没有响应) 1. 应用程序使用 WIFI 连接到 web 服务。 2. 成功接收到响应。 3. 连接切换到 3G。WIFI 被禁用,3G 被启用。 4. 应用程序使用 3G 再次连接到 web 服务。 5. 没有收到响应或错误。应用程序一直在等待响应。在调用 getResponseCode 之前显示了最后一个日志。
4. 连接从 3G 切换到 WIFI(正常) 1. 应用程序使用 3G 连接到 web 服务。 2. 成功接收到响应。 3. 连接切换到 WIFI。3G 被禁用,WIFI 被启用。 4. 应用程序使用 WIFI 再次连接到 web 服务。 5. 成功接收到响应。
我猜测默认情况下,HttpURLConnection 认为 WIFI 比 3G 更好的连接类型。因此,当连接从 WIFI 切换到 3G 时,HttpURLConnection 拒绝承认 3G,并仍然尝试使用 WIFI 进行连接。另一方面,HttpURLConnection 允许从 3G 切换到 WIFI,因为 WIFI 是更好的连接类型。我的猜测是否正确?如果是这样,我该如何允许从 WIFI 到 3G 的切换?
以下是我的代码片段(每次连接到 web 服务时都会调用它)。
//open new connection
httpsURLConnection = (HttpURLConnection) ((new URL(url)).openConnection());
httpsURLConnection.setDoInput(isDoInput);
httpsURLConnection.setDoOutput(isDoOutput);

try
{
    //supply parameters
    OutputStreamWriter wr = new OutputStreamWriter(httpsURLConnection.getOutputStream());
    wr.write(data);
    wr.flush();

    if(httpURLConnection != null)
    {
        if (httpsURLConnection.getResponseCode() == HttpsURLConnection.HTTP_OK) //connection hangs here
        {
            //some code
        }
        else
        {
            //some code
        }
    }

}catch(Exception e)
{

}
2个回答

2

我不确定为什么,在代码中添加System.setProperty("http.keepAlive", "false")可以解决问题。

根据Android开发者博客(androids-http-clients),在Froyo之前,HttpURLConnection存在一个bug,可以通过像上面那样禁用连接池来解决。然而,我使用的是Gingerbread,所以我不确定为什么HttpURLConnection在我的应用程序中仍然表现不佳。

对于其他人:如果您能提供更多解释,请毫不犹豫地编辑我的帖子。


1

当您在WiFi上建立连接并切换回3G时,是否会出现任何连接中断异常?

据我所知,如果您在WiFi上打开连接,则无法将同一连接用于3G。您需要拆除现有连接并在3G上重新建立新连接。

我猜测您的问题可能是因为您没有为请求设置任何连接超时,因此当连接断开时,HttpUrlConnection需要很长时间才能意识到您的连接已丢失。

我已经组合了一些默认超时的实用程序库,用于http连接,请查看是否可以帮助您解决问题。

https://github.com/nareshsvs/android-libraries


谢谢,Naresh!请注意,我的连接不会自动从WiFi切换到3G。在启用3G之前,我会手动禁用WiFi。据我所知,我没有重复使用以前的连接。在连接到Web服务之前,我总是调用httpsURLConnection =(HttpURLConnection)((new URL(url))。openConnection()); 因此,在尝试连接到Web服务之前,我的连接始终得到更新。此外,如果我从3G切换到WiFi,我仍然可以连接到Web服务。只有当我从WiFi切换到3G时才无法工作。 - Arci
另外,调用(HttpURLConnection)((new URL(url))。openConnection())是否意味着我正在重新建立新连接?还是它仍然只使用我的旧连接,只是具有不同的URL? - Arci
是的,它建立了一个新的连接。我建议您在Android中切换到HttpClient,它比HttpUrlConnection更有用和可配置。 - Naresh
谢谢!HttpClient适用于Eclair和Froyo,但HttpURLConnection是Gingerbread及以上版本的首选。虽然HttpClient更加可配置,但HttpURLConnection更快。顺便说一句,我已经解决了我的问题。 :) System.setProperty("http.keepAlive", "false")可以解决它。我不知道为什么。 - Arci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接