java - 在 AsyncTask 中更新后自动/立即更新进度条
问题描述
我有一个AsycTask
执行操作,例如在应用程序中复制或移动文件,并且我经常使用publishProgress()
.
问题
该代码几乎可以正常工作,尽管当AsyncTask
执行操作并更新进度条(调用)setProgress()
时onProgressUpdate()
,它不会立即更新,直到任务完成......但TextView
在同一位置更新的内容会更新。
我尝试了一种解决方法...sleep(1)
在AsyncTask
线程中使用以允许主线程执行(更新进度条:-))。这有效,并且随着文件被删除,进度条得到了更新......但是执行时间有很大差异,如下所示。
添加前 sleep(1)
删除的文件总数 -3804
平均花费时间 - 5s
(平均 3 次测试)
添加后 sleep(1)
删除的文件总数 -3804
平均花费时间 - 1m 40s
(平均 3 次测试)
如您所见,这sleep(1)
导致了执行时间的巨大变化。有没有另一种方法来解决这个问题......为了使进度条自动更新
,我非常感谢任何建议......这里是代码......
注意:我尝试使用另一个下载的文件管理器应用程序删除相同的文件,该应用程序在删除过程中显示一个进度条,并且时间与我添加 sleep(1) 的测试相关(1m 40s)
我的 doInBackground()
@Override
protected Boolean doInBackground(HashMap.SimpleImmutableEntry<Integer, File[]>... args) {
mTask = args [0].getKey ();
mFiles = args [0].getValue ();
// This calls the method according to task
switch (mTask) {
case TASK_COPY:
return copy ();
case TASK_MOVE:
return move ();
...
}
}
我的 onProgressUpdate()
(我更新视图的地方,我打电话时经常调用它publishProgress()
)
@Override
protected void onProgressUpdate (Object[] values) {
...
// THIS IS WHERE I UPDATE VALUES OF PROGRESS BAR IN PERCENTAGE
// instance fields
// private AtomicLong mProgress, mLimit
double i = mProgress.get (), j = mLimit.get ();
int k = ((int) (j < 1 ? 0 : (i / j) * 100));
// THIS mTextView updates properly immediately
mTextView.setText (mTaskMsg + k + "%\t\t" + mProgress.get () + "/" + mLimit.get ());
// but this progress bar does update until task is fully done (that is to 100) unless i sleep(1)
mProgressBar.setProgress (k, true);
}
从 asynctask 线程调用的其他方法...
// implemented FileVisitor
@Override
public FileVisitResult visitFile (Path path, BasicFileAttributes attrs) {
mProgress.incrementAndGet ();
publishProgress ();
// THIS IS WHERE I AM FORCED TO SLEEP TO ALLOW PROGRESS UPDATE IN MAIN THREAD
try {
Thread.sleep(1); // NOT REALLY THE BEST I KNOW...
Files.delete (path); }
catch (Throwable t) {
publishProgress (ERROR_CODE, t); }
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed (Path path, IOException io) {
mProgress.incrementAndGet ();
publishProgress (ERROR_CODE, io);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory (Path path, IOException io) {
mProgress.incrementAndGet ();
publishProgress ();
try {
Files.delete (path); }
catch (Throwable t) {
publishProgress (ERROR_CODE, t); }
return FileVisitResult.CONTINUE;
}
...
private boolean delete () {
publishProgress ();
try {
if (mFiles [0].isDirectory ()) {
Stream<Path> s = Files.walk (mFiles [0].toPath ());
// I count the files here myself because the count method
// of the stream crashes if files are 3000+ the app with no exception...i caught Throwable.
// Though its not the issue...
s.forEach (this);
publishProgress ();
Files.walkFileTree (mFiles [0].toPath (), this);
}
else {
mLimit.incrementAndGet ();
mProgress.incrementAndGet ();
publishProgress ();
return mFiles [0].delete ();
}
}
catch (Throwable t) {
publishProgress (ERROR_CODE, t); }
return false;
}
解决方案
推荐阅读
- node.js - B2B场景中的用户登录
- javascript - 为什么没有将局部函数分配给全局对象(窗口)?
- python - 如何需要两个 jsonschema 属性之一,但还要设置默认值?
- reactjs - Material-UI 样式和 html/markdown
- visual-studio-code - 使用 Atmel-Ice 在 Visual Studio Code 中调试 Arduino Due
- ruby - 如何制作一个 Ruby 方法来制作具有“n”宽度的星号钻石?
- python - 使精灵在点击时消失
- sql - 通过在 Hive/Athena 的 CSV 文件中添加两列来创建外部表
- android - 深度链接在 chrome expo react native 项目中不起作用
- python - 在 MacOS Big Sur 上安装 Python3.4 时出错