Android/Java:如何在5秒后停止下载?
我使用AsyncTask下载文件,目的是测量连接的下载速度。我想在5秒后停止下载,以便检查下载的总字节数并计算速度。下面是我正在使用的代码(放在doInBackground()方法中):Android/Java:如何在5秒后停止下载?,java,android,networking,Java,Android,Networking,我使用AsyncTask下载文件,目的是测量连接的下载速度。我想在5秒后停止下载,以便检查下载的总字节数并计算速度。下面是我正在使用的代码(放在doInBackground()方法中): 试试{ InputStream is=新URL(“http://www.domain.com/linux.iso)。openStream(); 字节[]buf=新字节[1024]; long startTime=System.nanoTime(); long limitTime=System.nanoTime(
试试{
InputStream is=新URL(“http://www.domain.com/linux.iso)。openStream();
字节[]buf=新字节[1024];
long startTime=System.nanoTime();
long limitTime=System.nanoTime();
长差=0;
而(差值<5000000000){/*50亿纳秒=5秒*/
is.read(buf);
limitTime=System.nanoTime();
差异=限制时间-开始时间;
}
is.close();
}
捕获(例外e){
e、 printStackTrace();
}
当连接到WiFi时,它工作正常。测得的速度非常准确,完成测试只需5秒。不过,一旦我转到3G,测试需要10到15秒的时间才能完成(我注意到连接速度越慢,完成测试所需的时间就越长)
为什么?我猜操作系统正在等待它发送的read()请求的回复,但不确定
你知道有什么方法可以让下载时间限制在5秒吗
提前感谢。您需要在不同的线程中分别计算和下载时间。你是对的,因为两者都在同一个线程中,
limitTime=System.nanoTime()代码>仅在为.read(buf)时执行代码>已完成read()
肯定是一个阻塞调用。但我认为这是因为必须等待手机中的手机收音机达到最大功率
一种确定的方法是打开浏览器,浏览页面,然后在页面加载后进行测试
今年有一个非常有趣的Google IO演讲,内容是关于手机收音机如何在大多数时间处于空闲/低功率状态,并且需要几秒钟来“预热”
我看看能不能找到视频的链接
编辑:以下是视频:
电池通话大约在17:12开始
上升约2秒,看起来是这样的
演示文稿中的幻灯片:
请尝试此代码,并告诉我它是否有效:
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);
}
}
final InputStream is=新URL(“http://www.domain.com/linux.iso)。openStream();
字节[]buf=新字节[1024];
最终字节[]buf=新字节[1024];
long startTime=System.nanoTime();
long limitTime=System.nanoTime();
长差=0;
ExecutorService executor=Executors.newCachedThreadPool();
可调用任务=新的可调用任务()
{
公共对象调用()
{
尝试
{
返回为。读取(buf);
}
捕获(IOE异常)
{
返回null;
}
}
};
长端时间=5000000000L;
while(差<结束时间)
{
未来=执行者提交(任务);
limitTime=System.nanoTime();
差异=限制时间-开始时间;
尝试
{
if(future.get(endTime-difference,TimeUnit.NANOSECONDS)==null)
{
System.out.println(“读取时引发IOException()!”;
}
}
捕获(TimeoutException例外)
{
System.out.println(“由于超时,引发了TimeoutException!”);
打破
}
捕获(例外e){}
最后
{
future.cancel(true);
}
}
如何将它们分开?将下载放在另一个线程中?是的,您可以让时间计算线程(或AsyncTask)在5秒过期时取消下载AsyncTask。我认为应该将InputStream作为一个全局变量,在取消下载线程后关闭它(以防止内存泄漏)。您还记得预热单元格需要多长时间/多少数据吗?好问题。我不记得了,但找到了信息并编辑了上面的答案。谢谢。在开始计时之前,我将确保在下载过程中等待2秒钟。请看下面我的答案:)
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);
}
}