使用 Wifi 的 Android 上的 HttpClient 会导致延迟(在初始请求时)

Posted

技术标签:

【中文标题】使用 Wifi 的 Android 上的 HttpClient 会导致延迟(在初始请求时)【英文标题】:HttpClient on Android using Wifi causes delay (on initial request) 【发布时间】:2011-04-26 18:29:07 【问题描述】:

我在 android 上遇到了 HttpClient 这个奇怪的问题。如果我尝试使用 WiFi 连接到 https url,则在发送实际请求之前会有延迟。如果我通过 3G 发送请求,则不存在延迟。

但它确实只发生在 Android 2.2 和 2.3 上,如果我在例如 2.1-update1 上运行它,它在 wifi 上也能正常工作。

但是,在初始请求之后立即发送请求时 - 它在 Wifi 上也能正常工作 - 但只是暂时的。然后它又回到需要 10 秒的时间,然后再正常运行一段时间......

在 2.3 上运行时: 11285 毫秒

在 1.6 上: 617 毫秒

我用来尝试解决这个问题的代码是这样的 HttpManager 和:

public class Main extends Activity 

Button button;
TextView text;

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v) 
            doRequest();
        

    );


private void doRequest() 
    HttpGet httpget = new HttpGet("https://url_goes_here/");

    HttpResponse httpResponse = null;
    try 
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        long before = System.currentTimeMillis();
        httpResponse = HttpManager.execute(httpget);
        long after = System.currentTimeMillis();

        HttpEntity entity = httpResponse.getEntity();
        String response = convertStreamToString(entity.getContent());
        Log.i("Test", response);

        TextView text = (TextView) findViewById(R.id.text);
        text.setText((String) "Time: " + (after-before) + "\n" + response);

     catch (Exception e) 
        e.printStackTrace();
        // Simplified code a bit
    


protected static String convertStreamToString(InputStream is) 

    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();

    String line = null;
    try 
        while ((line = reader.readLine()) != null) 
            sb.append(line + "\n");
        
     catch (IOException e) 
        e.printStackTrace();
     finally 
        try 
            is.close();
         catch (IOException e) 
            e.printStackTrace();
        
    
    return sb.toString();

出现延迟的那一行是 HttpManager.execute(httpget);这也是我计算 ms 的那一行。

有人遇到过这个问题吗?我发现这种延迟非常烦人,我的用户也会如此。模拟器的行为方式与运行 2.1-update1 的 Xperia Mini Pro 相同,它可以在 Wifi 上正常运行,而运行 CyanogenMod 7 (2.3) 的 HTC Desire 则无法正常运行。

【问题讨论】:

【参考方案1】:

android 附带的 ssl 堆栈存在问题。我也为此苦苦挣扎。到 apache 主页,获取 org.apache.http java 包(我使用的是 v4.1)。将其包含在您的应用程序中并直接使用其中的 HttpClient,而不是使用 Android 内置的 HttpClient,您的 SSL 握手延迟问题将得到解决。

【讨论】:

不幸的是,这似乎不起作用。另外,如果这是问题,为什么它会在 3G 而不是 wifi 上工作? :// 嗯...我看到的是,在 wifi 上,SSL 握手延迟由于连接速度而更加明显,而 3G 上的其他延迟问题掩盖了时间。我在多个设备上看到了 wifi 与 3G 的一些非常奇怪和不一致的行为。值得注意的是,正如您所描述的,我们在 Backflip 上的 os 1.6 上完全没有问题。根据您对第一次问题的描述,您必须重用您的 HttpClient,这很好,但它再次指出 SSL 握手是时间接收器,因为不需要对每个请求执行。 嗯,好吧。只是为了确保我正确添加了 httpclient.4.1.1.jar、httpcore-4.1.jar 和 httpmime-4.1.1.jar……我唯一需要做的就是将它们添加到构建路径中,对吗? 奇怪的是,如果我通过 wifi 尝试 api.myphotodiary.com,我会在第一次请求时延迟 10 秒,但是如果我尝试一些 graph.facebook.com url,我会得到 500 毫秒要求。都通过 SSL :/ 这个问题真的开始让我感到困惑...... 您可以包含 jar,但您可能想要获取源代码,因此您只需要包含特定的类,以减小应用程序的大小。然后确保您直接导入 org.apache.http.v4_1.client.HttpClient 和相关类,这样应用程序就不会使用内置的。我希望这对你有帮助!【参考方案2】:

在您的路由器上禁用 DNS 中继!它对我有用!

此外,没有任何版本的 httpclient 或 httpcore 为我改变它。

【讨论】:

以上是关于使用 Wifi 的 Android 上的 HttpClient 会导致延迟(在初始请求时)的主要内容,如果未能解决你的问题,请参考以下文章

wifi-direct端连接到Android上的对等点?

wifi上的Android网络浏览器地理位置问题 - 它的路要走

列出 Android Q / API 29 上的 WiFi 网络

同一路由器上的Android wifi设备通信

如果通过应用程序连接到 WIFI,则无法在 Android 上发送 http 请求

是否可以通过 iOS/Android 上的应用程序控制 WiFi/热点/BT 功能