第一次HTTP POST和GET尝试总是很慢 - 这个操作系统是相关的还是网络?

时间:2012-06-13 04:44:51

标签: android http networking http-post http-get

我现在刚刚开始在HTTP中弄湿我的脚。我一直使用GET和POST计算简单的HTTP请求。我使用的网页是3行php检查正确的$ _GET []和$ _POST []然后只是回显字符“1”。 我使用POST和GET使用相同的单个短名称/值对,希望不需要数据包碎片来解决问题,所有这些都是在一个脱离UI线程的线程上完成的。在计时时,请求会在手机上多次循环。一切顺利。 (见下面的代码)也就是说,我回复了“1”的回答。但是存在一个持续的时间问题。 我观察到的是:

  1. 在第一次尝试中,发出请求的时间比GET和POST方法中的后续trys要长得多。

  2. 其余的尝试总是快得多。

  3. GET总是比POST快。

  4. 所有这些都适用于3G和Wifi连接(但总体上Wifi的速度要快得多)。

    我已经尝试使用BasicResponseHandler(),并使用更多手动缓冲IO流方法,结果相同。

    我相信我理解3.因为POST需要两个传输,一个用于'HTTP 100'然后返回数据包主体。 - 这是对的吗?

    我的主要问题是第一次请求尝试发生的速度如此之慢?有时需要几秒钟(!)。是网络是什么东西或Android将它放入创建某种队列的套接字?如果是Android,有没有办法更正确地编码并避免这种情况?是否有关于保持套接字打开以使其在执行期间只出现一次的问题?如果是这样,这样做是好的做法吗?不可否认,我最无能为力。

    我已经找到了一些关于此的讨论,但没有一个直接达到这个方面。

    -

    GET和POST方法的基本代码如下所示(减去try / catches),并在UI的线程中执行,首先是GET方法然后是POST方法:(下面的输出)

    获取部分内容:

    public String[] HTTPGETIt(int numrounds)
    {
     HttpClient httpclient = new DefaultHttpClient();
     httpclient.getParams().setParameter (CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); 
     HttpGet GETRequest = new HttpGet("http://mypage.com/epoch.php?mynameis=tam");
     ResponseHandler <String> MyBRH = new BasicResponseHandler();
     String[] GETResult = new String[numrounds];
    
     int i = 0;
     long timestart, DT;
     while(i < numrounds)
     {
      timestart = System.currentTimeMillis();
      GETResult[i] = httpclient.execute(GETRequest, MyBRH);
      DT = System.currentTimeMillis() - timestart;
      Log.d(TAG, "(" + i + ") GET-Round Trip was "+ DT + " ms.");
      i++;
     }//while i <= numrounds
     httpclient.getConnectionManager().shutdown();
     return GETResult;
    } //END HTTPGETIt
    

    和POST版本:

    public String[] HTTPPOSTIt(int numrounds)
    {
     String Place = "HTTPPostping";
     HttpClient httpclient = new DefaultHttpClient();
     httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); 
     HttpPost PostRequest = new HttpPost("http://mypage.com/epoch.php");
     ResponseHandler <String> MyBRH = new BasicResponseHandler();
     String[] POSTResult = new String[numrounds];
    
     List<NameValuePair> MynameValuePairs = new ArrayList<NameValuePair>(2);
     MynameValuePairs.add(new BasicNameValuePair("mynameis", "tam"));
    
     PostRequest.setEntity(new UrlEncodedFormEntity(MynameValuePairs));
    
     int i = 0;
     long timestart, DT;
     while(i < numrounds)
     {
      timestart = System.currentTimeMillis();
      POSTResult[i] = httpclient.execute(PostRequest, MyBRH);
      DT = System.currentTimeMillis() - timestart;
      Log.d(TAG, "(" + i + ") POST-Round Trip was "+ DT + " ms.");
      i++;
     }//while i <= numrounds
     httpclient.getConnectionManager().shutdown();
     return POSTResult;
    } // END HTTPPOSTIt
    

    这些被称为:

    Runnable HTTPGETJob = new HTTPGETTask(NS);
    Thread HTTPGETThread = new Thread(HTTPGETJob, "HTTPGETThread");
    HTTPGETThread.setPriority(Thread.MAX_PRIORITY);
    HTTPGETThread.start();
    

    Runnable HTTPPOSTJob = new HTTPPOSTTask(NS);
    Thread HTTPPOSTThread = new Thread(HTTPPOSTJob, "HTTPPOSTThread");
    HTTPPOSTThread.setPriority(Thread.MAX_PRIORITY);
    HTTPPOSTThread.start();
    

    使用runnables:

    class HTTPGETTask implements Runnable
    {
     int numtimes;
     DeviceInfo tsrtDI;
     HTTPGETTask(int inNS) {
      this.numtimes = inNS;
     }
    
     @Override
     public void run() 
     {
      long [] TT2NS = new long[numtimes];
      TT2NS = HTTPGETIt(numtimes);
     }
    };
    

    class HTTPPOSTTask implements Runnable
    {
     int numtimes;
     DeviceInfo tsrtDI;
     HTTPPOSTTask(int inNS) {
      this.numtimes = inNS;
     }
    
     @Override
     public void run() 
     {
      long [] TT2NS = new long[numtimes];
      TT2NS = HTTPPOSTIt(numtimes);
     }
    };  
    

    输出通常是:

    (0)GET-Round Trip是368 ms。

    (1)GET-Round Trip是103 ms。

    (2)GET-Round Trip是98毫秒。

    (3)GET-Round Trip是106 ms。

    (4)GET-Round Trip是102 ms。


    (0)回合后旅行是1289毫秒。

    (1)回合后旅行是567毫秒。

    (2)回合后旅行是589毫秒。

    (3)回合后旅行是496毫秒。

    (4)回合后旅行是557毫秒。

2 个答案:

答案 0 :(得分:1)

我会坚持要将Protocol Version设为HTTP 1.1并尝试一下。它会增加请求/响应时间,而不是现在需要的时间。我没有尝试过,只是得到了信息。因此,您可以在执行请求之前尝试类似下面的内容。

httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, 
                                                        HttpVersion.HTTP_1_1);

答案 1 :(得分:1)

我同意Lalit Poptani的答案,这可能有助于更快地拨打电话,因为它似乎是因为HTTP 1.1保持连接并且不会每次都握手。

但与此同时,我想说这不是Android特有的问题,几乎每个平台和每种语言都会发生同样的事情,因为第一次当你进行任何http调用时平台需要创建和设置不同的对象,为其分配值以执行调用,并保留在那里,因此当您进行新调用时,将保存创建和分配对象的时间,从而获得更快的响应。

这些对象是哪个? - 在上面的行中说:我没有任何相当明确的列表,但它们就像代理设置,缓存内存。


再等几句,直到有人对此有深入的技术知识,并解释所有内容如何在后面工作。