Android AsyncTask - 执行顺序

11

我遇到了一个关于AsyncTasks执行顺序的问题。

我的问题是:

假设我有两种AsyncTask的实现: MyAsyncTask1MyAsyncTask2

它们是以以下方式调用的:

new MyAsyncTask1 ().execute ();
new MyAsyncTask2 ().execute ();

保证MyAsyncTask1MyAsyncTask2之前执行吗? 可以确定的是,它们不会并行执行,因为使用了默认的执行器,即SERIAL_EXECUTOR。 问题在于执行顺序:哪个任务会先执行?

如果执行顺序未确定,如何强制执行AsyncTasks的顺序?

我需要的是让MyAsyncTask1MyAsyncTask2之前执行,这并不总是发生,即使我在MyAsyncTask2之前调用了MyAsyncTask1的execute方法。

实际上,我有一个自定义活动:

public abstract class CustomActivity extends Activity {

    @Override
    protected void onCreate ( Bundle savedInstanceState ) {
        super.onCreate ( savedInstanceState );
        new MyAsyncTask2 ().execute ();
    }
}

还有一个继承自自定义活动的活动:

public class MainActivity extends CustomActivity {

    @Override
    protected void onCreate ( Bundle savedInstanceState ) {
        new MyAsyncTask1 ().execute ();
        super.onCreate ( savedInstanceState );
    }
}

所以如果我使用MainActivityMyAsyncTask1 应该在 MyAsyncTask2 之前执行,至少这是我需要的行为。


1
在MyAsyncTask1的onPostExecute中启动MyAsyncTask2,这样MyAsyncTask2总是在MyAsyncTask1之后执行。 - ρяσѕρєя K
你好,伊姆兰·汗,感谢你的建议,但这是不可能的,因为我的设计。CustomActivity(和MyAsyncTask2)被其他活动(使用继承)使用,在那里我根本不想调用MyAsyncTask1。 - Leeeeeeelo
1
然后只需将要启动MyAsyncTask2的Activity名称传递给CustomActivity(和MyAsyncTask2)构造函数,如果您不想启动MyAsyncTask2,则传递null给其他活动。 - ρяσѕρєя K
1
你可以在CustomActivity(和MyAsyncTask2)中使用context.getPackageManager().getClass();来获取用户当前查看的活动名称。 - ρяσѕρєя K
6个回答

5

确保两个线程(基本上就是AsyncTask)按照你想要的顺序执行的唯一方法是在第一个线程完成后启动第二个线程。

在您的情况下,为了使实现抽象化并避免在AsyncTask1的onPostExecute中实际调用AsyncTask2(Anup和Sanket建议的方式也可以混合使用,如果您想要混合使用),请让AsyncTask1调用super.executeAsyncTask2(),其中executeAsyncTask2()是您的CustomActivity中启动第二个AsyncTask的方法。


你好 zrgiu!你真正理解了我的设计。如果我要使用你的建议,那么你如何建议在CustomActivity中调用MyAsyncTask2?(除了在每个子类中调用你建议的方法之外) - Leeeeeeelo
由于您的AsyncTask1必须以某种方式从另一个类中调用该方法,我看不出其他方法。抱歉。 - zrgiu

3
为了“链接”任意数量的AsyncTasks,我所做的是将自己的AsyncTasks作为参数接收一个自定义的回调函数。你只需要像这样定义它:
public interface AsyncCallback(){
    public void onAsyncTaskFinished();
}

您的AsyncTask实现构造函数应该有一个AsyncCallback作为参数,就像这样:
private AsyncCallback callback;

public AsyncTaskImplementation(AsyncCallback callback){
    //Do whatever you're doing here
    this.callback = callback;
}

当然,如果它们有更多参数,请不要删除它们。
然后,在 onPostExecute 结束之前,加入以下内容:
if (callback != null) callback.onAsyncTaskFinished();

如果你传递了一个回调函数,AsyncTask将在主线程中执行你的回调函数。如果你不想执行任何回调函数,只需传递null

因此,要调用你的AsyncTask链,只需编写以下代码:

new AsyncTask1(new AsyncCallback(){

    public void onAsyncTaskFinished(){
         new AsyncTask2(null).execute();
    }

}).execute();

我希望这能对你有所帮助 ;-)

0

在第一个异步任务的onPostExecute()方法结束时调用您的第二个异步任务。

//first async task's onPostExecute method

onPostExecute()
{
//do your stuff and call second async task

new MyAsyncTask2 ().execute ();

}

这将以简单而优雅的方式保证第二项任务在第一项任务之后执行。


0
在第一个任务的onPostExecute中调用第二个任务,如下所示:
@Override
protected void onPostExecute(String string){//String or whatever u passed
    new MyAsyncTask2 ().execute ();
}

-1

AsyncTask在后台执行,所以在您的情况下,第一段代码将启动task1,并立即启动task2...因此调用

new MyAsyncTask2 ().execute ();

将此代码放入Task1的postexecute中


-1
不要让事情变得复杂,尽量保持你的设计简单和清晰。你的两个AsyncTasks之间的竞争取决于它们在重写方法中所承载的处理量。逻辑上来说,如果你想让AsyncTask1在AsyncTask2之前完成,那么只需将第二个Async的代码块添加到第一个Async中即可。
或者从第一个Async的onPostExecute中启动第二个Async——但就个人而言,这似乎是不必要的。

1
你好,Waqas。感谢你的建议,但我相信我的设计很简单。主要思路是:在许多情况下我使用自定义活动(使用继承),每个情况都有自己的实现; CustomActivity 包含共同的基本部分,而其每个子类添加了特定的内容。因此,我不能简单地将 AsyncTask2 的内容添加到 AsyncTask1 中。 - Leeeeeeelo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接