有两个AsyncTasks序列:
A -> B -> C
D -> E -> F
位于onPostExecute
,任务A
启动任务B
,onPostExecute
启动任务C
。第二个序列也是如此。
如果序列是这样开始的:
new A().execute();
// at a later time, but while A is still executing
new D().execute();
在任务D
完成之前,是否存在确保任务C
未启动的方法有哪些?
答案 0 :(得分:1)
有一个框架允许"序列"和"链"异步调用:https://github.com/BoltsFramework/Bolts-Android
要获得更高级的执行控制,请查看RxJava:https://github.com/ReactiveX/RxJava
此外,您可以在将来将这些问题与执行模式分离。也就是说,用相应类的简单方法编写代码,不要做任务"任务"。单独创建任务作为某些方法调用的纯容器,可以从后台或前台调用任何给定函数序列。
答案 1 :(得分:0)
实际上在最新的Android版本中,AsyncTask已经在单线程池执行器上运行。但是为了不依赖于默认行为,您可以在自己的Executor上运行它。所以你可以创建单线程执行器:
Executor singleThreadExecutor = Executors.newSingleThreadExecutor();
然后逐个运行AsyncTask
:
synchronize (tasksLock) {
new A().executeOnExecutor(singleThreadExecutor);
new B().executeOnExecutor(singleThreadExecutor);
new C().executeOnExecutor(singleThreadExecutor);
}
// on some your event
synchronize (tasksLock) {
new D().executeOnExecutor(singleThreadExecutor);
new E().executeOnExecutor(singleThreadExecutor);
new F().executeOnExecutor(singleThreadExecutor);
}
执行程序保证它们将按调用executeOnExecutor
的顺序启动。
答案 2 :(得分:0)
您可以将其视为任务队列。如果您正常启动task.execute()
(仅拨打task.execute()
) - >每个任务都将被推送到UI线程的线程中的队列中。首先调用,将首先执行。因此,您的任务将逐个开始,首先根据首先调用的tasks
开始。
如果您要调用两个threads
的2个序列else
我建议您使用ExecutorService。
早期版本的Android OS有一些重要的注意事项:
首次引入时,AsyncTasks在单个后台线程上串行执行。从DONUT开始,这被改为一个线程池,允许多个任务并行运行。从HONEYCOMB开始,任务在单个线程上执行,以避免由并行执行引起的常见应用程序错误。如果您真的想要并行执行,可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor,Object [])。
答案 3 :(得分:0)
试试这个
*在执行任务时将任务A放入变量。
A taskA = new A();
taskA.execute();
*之后您必须检查任务A是否正在运行
if (taskA != null && taskA.getStatus() == A.Status.RUNNING) {
// Task A still running
return;
}else{
// Task A completed
new D().execute();
}
答案 4 :(得分:0)
一个简单的队列现在可以使用:
public class OperationsQueue {
private Operation ongoingOperation;
private Queue<Operation> queue = new LinkedList<>();
public void execute(Operation operation) {
if (ongoingOperation != null)
queue.add(operation);
else {
ongoingOperation = operation;
operation.setOnFinishedCallback(() -> operationFinished(operation));
operation.execute();
}
}
private void operationFinished(Operation operation) {
ongoingOperation = null;
Operation nextOperation = queue.poll();
if (nextOperation != null)
execute(nextOperation);
}
}
public abstract class Operation {
protected Runnable onFinished = () -> { };
public abstract void execute();
public void setOnFinishedCallback(Runnable onFinished) {
this.onFinished = onFinished;
}
}
Operation
的具体实现需要在序列中启动第一个异步任务,最后一个异步任务必须调用onFinished。
这是在这个序列的情况下:
A -> B
操作会将回调传递给异步任务A
,并将其传递给它启动的异步任务,以便上一个任务B
在其onPostExecute
中调用它:
class SomeOperation extends Operation {
public void execute() {
new A(() -> onFinished()).execute();
}
}
class A extends AsyncTask<Void, Void, Void> {
//...
public Runnable onSuccess;
public A(Runnable onSuccess) {
this.onSuccess = onSuccess;
}
onPostExecute() {
new B(onSuccess).execute();
}
}
class B extends AsyncTask<Void, Void, Void> {
//...
public Runnable onSuccess;
public B(Runnable onSuccess) {
this.onSuccess = onSuccess;
}
onPostExecute() {
onSuccess.run();
}
}
SomeOperation
及其基础任务现在可以连续执行:
OperationsQueue queue = new OperationsQueue();
queue.execute(new SomeOperation());
queue.execute(new SomeOperation());
第二个A
的任务SomeOperation
将在第一个任务B
完成后才会执行。