2012-09-11 37 views
3

我正在使用AsyncTask来下载文件,目的是测量连接的下载速度。我想在5秒后停止下载,以便我可以检查下载的总字节数并计算速度。下面是我使用(这被放置在doInBackground()方法中)的代码:Android/Java:如何在5秒后停止下载?

try{     
    InputStream is = new URL("http://www.domain.com/linux.iso").openStream(); 
    byte[] buf = new byte[1024]; 

    long startTime = System.nanoTime(); 
    long limitTime = System.nanoTime(); 
    long difference = 0;  

    while (difference < 5000000000){ /*5 billion nanoseconds = 5 seconds*/ 
     is.read(buf); 
     limitTime = System.nanoTime(); 
     difference = limitTime - startTime; 
    }   

    is.close(); 
} 
catch(Exception e){ 
    e.printStackTrace(); 
} 

当连接到无线网络,这是工作的罚款。测得的速度非常准确,完成测试需要5秒。但是,一旦我转移到3G,测试需要10到15秒才能完成(我注意到连接越慢,完成时间就越长)。

怎么回事?我猜测操作系统正在等待它发送的read()请求的回复,但不确定。

你知道一种方法,无论如何都会在5秒内限制下载吗?

在此先感谢。

+0

在我的答案采取:) –

回答

1

read()绝对是阻塞呼叫。但我认为这是等待手机中的手机无线充电的结果。

确定的一种方法是打开浏览器,浏览页面,然后在页面加载完成后进行测试。

有一个非常有趣的谷歌IO谈谈小区的无线怎么坐在空闲/低功耗状态的大部分时间,今年和需要几秒钟的“热身”

我会看看我能否找到视频的链接。

编辑:这里的视频:

http://www.youtube.com/watch?v=PwC1OlJo5VM

电池通话时间则在大约17:12

http://www.youtube.com/watch?v=PwC1OlJo5VM&feature=player_detailpage#t=1032s

斜坡上升为约2秒,它看起来像。

从文稿的幻灯片:

enter image description here

+0

你还记得为单元格加热需要多长时间/多少数据? –

+0

好问题。我不记得,但找到了信息并编辑了上面的答案。 – pjco

+0

谢谢。在开始我的时间之前,我会确保等待2秒钟。 –

2

您需要在不同的线程中分开时间计算和下载。你是对的,因为两者都在同一线程中,limitTime = System.nanoTime();只会在is.read(buf);完成时才会被执行

+0

下面一起来看看如何将它们分开虽然?把下载里面另一个线程? –

+0

是的,您可以让时间计算线程(或AsyncTask)在5秒钟过期时取消下载AsyncTask。我认为你应该把InputStream作为一个全局变量在取消下载线程之后关闭它(以防止内存泄漏)。 –

+0

哎呀。谢谢您的帮助。 –

0

试试这个代码,让我知道,如果它的工作原理:

final InputStream is = new URL("http://www.domain.com/linux.iso").openStream(); 
byte[] buf = new byte[1024]; 

final byte[] buf = new byte[1024]; 
long startTime = System.nanoTime(); 
long limitTime = System.nanoTime(); 
long difference = 0; 

ExecutorService executor = Executors.newCachedThreadPool(); 
Callable<Object> task = new Callable<Object>() 
{ 
    public Object call() 
    { 
     try 
     { 
      return is.read(buf); 
     } 
     catch(IOException e) 
     { 
      return null; 
     } 
    } 
}; 

long endTime = 5000000000L; 

while(difference < endTime) 
{ 
    Future<Object> future = executor.submit(task); 
    limitTime = System.nanoTime(); 
    difference = limitTime - startTime; 

    try 
    { 
     if(future.get(endTime - difference, TimeUnit.NANOSECONDS) == null) 
     { 
      System.out.println("IOException is raised on read()!"); 
     } 
    } 
    catch(TimeoutException ex) 
    { 
     System.out.println("TimeoutException is raised, because of the timeout!"); 
     break; 
    } 
    catch(Exception e){} 
    finally 
    { 
     future.cancel(true); 
    } 
}