Android AsyncTask每秒都会复制和更新

时间:2015-09-05 16:51:15

标签: android android-asynctask

我想在后台复制一个文件,并且每隔n秒更新一次进度。

现在,当新百分比大于之前的百分比时,下面的代码会更新进度。这对于小文件来说是分崩离析的,因为它变得如此之快并且滞后于UI线程。

所以我的问题是如何在后台复制文件,但每隔n秒发布一次进度。另外,我如何计算复制的速度?

我试图模仿的一个很好的例子是下载通知,它显示速度,百分比并以〜2000ms间隔更新它们

这是我用来复制process(INPUTS) begin <your code> end process; 方法

的代码
doInBackground()

2 个答案:

答案 0 :(得分:2)

您可以减少publishProgress来电,并仅在预定义的时间间隔内调用。

只需添加更新的最短时间间隔即可。例如,这将以最多半秒的速率更新:

private static long UPDATE_DELAY = 500; // Delay in millis

// Start with 0 progress
publishProgress("0");

...

long currentTime = System.currentTimeMillis();
if ((currentTime - startTime > UPDATE_DELAY) &&
    (percentDone != latestPercentDone)) {
    percentDone = latestPercentDone;
    publishProgress(""+percentDone);
    startTime = currentTime;
}

...

// End with 100 progress
publishProgress("100");

答案 1 :(得分:0)

基本上每隔一段时间报告一次的方法就是使用这样的循环:

long reportTime = System.currentTimeMillis(); // first report after first processing
while (!done) {
    // do processing
    if (System.currentTimeMillis() >= reportTime) {
         // do progress report
         reportTime = System.currentTimeMillis() + 2000; // next report in 2 secs
    }
}

计算复印速度可以采用不同的方式。最简单的方法是划分当前运行时复制的当前字节:

long startTime = System.currentTimeMillis();
long totalBytesCopiedSoFar = 0;
while (!done) {
    // do processing, and update totalBytesCopiedSoFar
    if (itIsReportingTime) {        
        long runTimeSoFarInMillis = System.currentTimeMillis() - startTime;
        long runTimeSoFarInSecs = runTimeSoFarInMillis / 1000;
        double copyingSpeedInBytesPerSec = (double) totalBytesCopiedSoFar / (double) runTimeSoFarInSecs;
    }
}

将两种模式组合并将其应用于您的代码,可以得到以下结果。我已经省略了您的设置并清理了代码,所以这不会编译,但您可以理解。

long startTime = System.currentTimeMillis();
long reportTime = System.currentTimeMillis(); // first report as soon as possible
long totalMegaBytes = new File(source).length();
while ((length = input.read(buffer)) > 0) {
    total += length;

    latestPercentDone = (int) ((total / (float) totalMegaBytes) * 100);

    long runTimeInSecs = (System.currentTimeMillis() - startTime) / 1000;
    double speedInBytesPerSec = (double) total / (double) runTimeInSecs;

    if (System.currentTimeMillis() >= reportTime) {
        publishProgress(""+latestPercentDone); // you may want to report the speed as well
        reportTime = System.currentTimeMillis() + 2000; // next report in 2000 ms
    }

    output.write(buffer, 0, length);
}