Android 4+应用应该执行长时间运行的操作。例如,这可能是将一百万个文件从A复制到B.为了不阻止UI,此操作使用AsyncTask
在后台运行。
假设操作在过程中间需要一些用户反馈以继续其工作,例如"文件XY已存在。覆盖,Irgnore或重命名?"
从用户那里获得此反馈的最佳方式是什么?由于操作在后台线程中运行,因此无法呈现AlertDialog
(或类似的东西)因为UI交互只能在主线程中进行...
所以我遇到了这些解决方案:
我不喜欢这些解决方案。在第一种情况下,即使根本不存在冲突,也要求用户提供反馈。如果必须按特定顺序处理步骤,则无法实现第二种解决方案。第三种解决方案会导致代码难以阅读/理解/维护。
一个好的解决方案是:
在Objectiv-C / iOS中使用GCD或在C#中使用async / await这不是一个大问题。但是如何使用AsyncTask
在Android中完成此操作?
答案 0 :(得分:0)
同时我想,我找到了答案here:只需在myActivity.runOnUiThread(...)
内运行doInBackground(...)
并等待它。听起来不错,但它不起作用。 AsyncTask /后台线程不等待Runnable
完成:
private void copyFiles() {
CopyTask copyTask = new CopyTask (this);
copyTask.execute();
}
private class CopyTask extends CustomAsyncTask<Void, Void, Void> {
private doCopy;
@Override
protected Boolean doInBackground(Void... params) {
// Custom code, e.g. copy files from A to B and check for conflict
for (File file : allFiles) {
doCopy = true;
if (isConflict(file)) {
// Stop current thread and ask for user feedback on UI Thread
Runnable uiRunnable = new Runnable() {
public void run() {
// Pos 1. --> Execute custom code, e.g. use AlertDialog to ask user if file should be replaced...
doCopy = false;
synchronized (this) {
this.notify();
}
}
});
synchronized(uiRunnable) {
// Execute code on UI thread
activity.runOnUiThread(uiRunnable);
// Wait until runnable finished
try {
uiRunnable.wait();
}
catch (InterruptedException e ) {
e.printStackTrace();
}
}
}
// Pos 2. --> Continue work
if (doCopy)
copyFromAToB(File);
}
return null;
}
}
我希望,当检测到冲突时,执行Runnable
并执行 Pos 1 (Runnable
内的代码以解决冲突) BEVOR到达Pos 2 。不是这种情况。 Runnable
已正确执行,但AsyncTask
并未等待它完成。 doInBackground
的执行继续执行而没有任何中断。似乎doInBackground
和Runnable
并行执行(因为它们在不同的线程上执行而不令人惊讶),但为什么doInBackground
不等待?