3

接続のダウンロード速度を測定する目的で、AsyncTask を使用してファイルをダウンロードしています。ダウンロードの合計バイト数を確認して速度を計算できるように、5 秒後にダウンロードを停止したいと考えています。これが私が使用しているコードです(これはdoInBackground()メソッド内に配置されています):

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();
} 

WiFiに接続すると、これは正常に機能します。測定された速度はかなり正確で、テストを完了するのにちょうど 5 秒かかります。ただし、3G に移行すると、テストが完了するまでに 10 秒から 15 秒かかります (接続が遅いほど、完了するまでに時間がかかることに気付きました)。

どうして?OS が送信した read() 要求の応答を待っていると推測していますが、よくわかりません。

何があってもダウンロードを 5 秒に制限する方法を知っていますか?

前もって感謝します。

4

3 に答える 3

2

時間の計算とダウンロードを別のスレッドに分ける必要があります。どちらも同じスレッドにあるため、完了しlimitTime = System.nanoTime();たときにのみ実行されます。is.read(buf);

于 2012-09-11T21:44:27.673 に答える
1

read()間違いなくブロッキングコールです。しかし、これは、電話のセル無線がフルパワーになるまで待たなければならなかった結果だと思います。

確実に判断する 1 つの方法は、ブラウザーを開いてページを閲覧し、ページが読み込まれた後にテストを行うことです。

今年の Google IO の非常に興味深い話では、セル無線がほとんどの場合アイドル/低電力状態にあり、「ウォームアップ」するのに数秒かかるという話がありました。

ビデオへのリンクを見つけることができるかどうかを確認します。

編集:ここにビデオがあります:

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

バッテリートーク開始 17:12頃

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

ランプアップは〜2秒のようです。

プレゼンテーションのスライド:

ここに画像の説明を入力

于 2012-09-11T21:44:41.463 に答える
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);
    }
}
于 2012-09-11T22:28:17.570 に答える