如何协调两个后台任务?

时间:2016-04-20 20:28:07

标签: java android multithreading android-fragments android-asynctask

我在片段中运行了2个AsyncTasks AsyncTasks是在不同的类中定义的,而不是片段的内部私有类 我遇到的问题是,现在我需要让AsyncTaskX等到AsyncTaskY完成其onPostExecute
我怎么解决这个问题呢? 我正在考虑使用倒计时,但是AsyncTaskY是在另一个类中,我不确定最好的编码方式是什么?
有没有办法检查AsyncTask是否完全完成?

更新
我想知道task.execute().get()之后onPostExecute会回来吗?

更新2:
从UI线程安全调用CountDownLatch.countDown()吗?

4 个答案:

答案 0 :(得分:1)

在没有看到您的代码的情况下确定这一点真的很难。一个肮脏的解决方案是添加一个静态布尔值,然后添加一个递归计时器。这不是最好的编程技术,但从我读到的它肯定会起作用。

在任何类

中创建一个静态布尔值
static boolean onPostExecuteFinished;
需要先完成的AsyncTask中的

将其设置为true

ClassName.onPostExecuteFinished = true;

在需要等待的类中,使用递归方法等待它完成。我建议使用处理程序。

public void nameOfRecursiveMethodHere()
Handler handler = new Handler()

handler.postDelated(new runnable........{
if (ClassName.onPostExecuteFinished) {
//Great it is finished do what you need
} else {
//Not finished call this method again
nameOfRecursiveMethodHere();
}

}),(put how often you want it to check in milliseconds here);

答案 1 :(得分:1)

我建议使用RxJavaRxAndroid,而不是使用2个AsyncTasks。并发性在那里变得更加容易。

例如,您可以执行以下操作来同步异步作业:

Observable<Object1> job1 = Observable.fromCallable(() -> yourCall2());
Observable<Object2> job2 = Observable.fromCallable(() -> yourCall2());

Observable.combineLatest(job1, job2, (object1, object2) -> yourMethod())
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(...);

这只是一个小而不完整的例子,但应该说明如何实现你想要的。我已经使用Lambda Expressions缩短了Code。这是通过使用Retrolambda完成的。您可以使用zip运算符实现相同的目标。

答案 2 :(得分:1)

正如@ Andy-Turner评论的那样,使用CountDownLatch是可能的,你也可以使用信号量来指示另一个任务的执行。

请检查此链接: http://tutorials.jenkov.com/java-concurrency/semaphores.html

答案 3 :(得分:1)

AsyncTasks在单个后台线程(from API 11)上串行执行。

一点点测试:

private static class AsyncTaskX extends AsyncTask<Void, Void, Void>{
    @Override
    protected Void doInBackground(Void... params) {
        for (int i = 0; i < 10; i++){
            Log.i("test order", "ping X "+ i);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return null;
    }
}

private static class AsyncTaskY extends AsyncTask<Void, Void, Void>{
    @Override
    protected Void doInBackground(Void... params) {
        for (int i = 0; i < 10; i++){
            Log.i("order", "ping Y" + i);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

日志:

test order: ping X 0
test order: ping X 1
test order: ping X 2
test order: ping X 3
test order: ping X 4
test order: ping X 5
test order: ping X 6
test order: ping X 7
test order: ping X 8
test order: ping X 9
order: ping Y0
order: ping Y1
order: ping Y2
order: ping Y3
order: ping Y4
order: ping Y5
order: ping Y6
order: ping Y7
order: ping Y8
order: ping Y9

如此长时间的工作人员可以阻止他人。

task.execute()。get()将在onPostExecute之前返回,你将阻止UI线程。

查看有关processes and threads and some gotchas的一般信息。

执行时间也很重要,因为AsyncTask只能用于需要几秒钟的任务/操作。