串行执行两个AsyncTasks序列

时间:2015-12-18 08:44:02

标签: android android-asynctask

有两个AsyncTasks序列:

  1. A -> B -> C
  2. D -> E -> F
  3. 位于onPostExecute,任务A启动任务BonPostExecute启动任务C。第二个序列也是如此。

    如果序列是这样开始的:

        new A().execute();
    
        // at a later time, but while A is still executing
        new D().execute();
    

    在任务D完成之前,是否存在确保任务C未启动的方法有哪些?

5 个答案:

答案 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完成后才会执行。