2012-09-11 35 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); 
    } 
}