2015-09-05 83 views
0

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

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

所以我的问题是如何复制背景中的文件,但每n秒发布一次进度。另外我怎样才能计算它的复制速度?

的什么,我试图模仿是一个下载通知一个很好的例子,它显示的速度,比例,并在〜2000毫秒间隔

这是我使用复制的代码更新它们,在doInBackground()方法

startTime = System.currentTimeMillis(); 
    FileInputStream input = null; 
    FileOutputStream output = null; 
    totalMegaBytes = new File(source).length(); 
    try { 
     input = new FileInputStream(source); 
     output = new FileOutputStream(dest); 
     byte [] buffer = new byte[8192]; 
     int length; 
     while ((length = input.read(buffer)) > 0) { 
      total += length; 
      latestPercentDone = (int) ((total/(float) totalMegaBytes) * 100); 
      if (percentDone != latestPercentDone) { 
       percentDone = latestPercentDone; 
       publishProgress(""+percentDone); 
      } 
      output.write(buffer, 0, length); 
     } 
     //flush remaning information 
     output.flush(); 
     //close stream 
     output.close(); 
     input.close(); 
+0

你一定要考虑的Rx对于这种或者问题,这将是很容易做到这一点:https://github.com/davidmoten/rxjava-file –

回答

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"); 
+0

这将先等待半秒,但随后每循环发布一次进度。 –

+0

这只是一个大方向。但无论如何修复它,只是为了安全起见。谢谢。 –

+0

@RobMeeuwisse:每次调用'publishProgress()'后都会更​​新'startTime'。 – cybersam

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