【问题标题】:Multiple AsyncTask's onPostExecute order多个 AsyncTask 的 onPostExecute 顺序
【发布时间】:2013-07-05 13:00:31
【问题描述】:

首先,很抱歉英语不好。我有 android 2.3,所以有“Real”并行 AsyncTask 而不是顺序执行(android 3.0 和更高版本)。 我有几个 AsyncTask,每个都执行 onPostExecute() 回调(我知道它将在 UI 线程中执行)。 假设我只有 2 个并行 AsyncTask,当第一个任务完成时,回调 onPostExecute() 将被调用。 是否有可能,当 onPostExecute()(来自第一个 AsyncTask)方法在 UI 线程上运行时,第二个任务正在调用其 onPostExecute() 方法,从而中断第一个 AsyncTask 的 onPostExecute() 的当前执行?

// 已更新 我现在用代码解释一下:

// AsyncTask1
onPostExecute(Result result) {
    activity->processResult1(result);
} 

// AsyncTask2
onPostExecute(Result result) {
    activity->processResult2(result);

假设 AsyncTask1 已经完成了它的工作,并且 processResult1() 是一个运行时间很长的方法: 当我们在 UI 线程上执行 processResult1() 时,AsyncTask2 完成了它的工作。 现在会发生什么?

  1. processResult1() 将被 processResult2() 中断
  2. processResult2() 一直等到 processResult1() 结束

【问题讨论】:

    标签: java android android-asynctask


    【解决方案1】:

    AsyncTask 完成它的doInBackground 方法时,它会将Runnable(它执行我们的onPostExecute 方法)发布到UI 线程。通过“post”,我的意思是存在某种Runnable 队列,这意味着这些方法(onPostExecute)将以串行方式(一个接一个)执行。因此,一个 onPostExecute 方法不能中断另一个(当然,如果它已经发布到 UI 线程中)。

    【讨论】:

    • 然而,在 onPostExecute 方法上执行的一个可运行对象可能会中断在 UI 线程之外执行的其他一些异步任务。我以为这就是赛勒斯要问的。
    • @WilliamMorrison 是的,你说得对。虽然,我想赛勒斯问的是两个已完成的任务:)
    • @CyrusSmith 我稍微编辑了我的答案。我指的是那些方法,而不是任务本身
    • @Dmitry Zaitsev,这实际上是我要找的,спасибо)!
    • @WilliamMorrison,抱歉我的解释不好,我说的是两个已完成的 AsyncTask,如 Dmitry 所述。
    【解决方案2】:

    首先“所以有”真实“”是错误的。所谓的“真正的”异步任务在更高版本的 android 上可用,无需太多技巧,您只需要以不同的方式调用它,因为默认方式已更改。

    【讨论】:

    • 是的,我知道它们在更高版本上可用。我只是在谈论默认行为。
    • 我在 android 文档中发现了这一点:“AsyncTask 保证所有回调调用都以这样一种方式同步,即以下操作在没有显式同步的情况下是安全的。”这是否意味着一个 onPostExecute() 不能被另一个 onPostExecute() 打断? (是的,我知道它可以被其他任务打断,比如事件处理)
    • @CyrusSmith,是的。这也是我的解释。马辛是正确的。
    • 我实际上问过这个问题:如果一个线程需要提交给 runOnUiThread(此时我们有一个在 UIThread 上执行的方法),它会等到方法结束,还是会中断执行它的工作?您的注释(stackoverflow.com/questions/17499435)-“......即使那样,如果它需要提交给 runOnUiThread,它可能会失败,因为正在进行长时间运行的操作。”,让我认为 onPostExecute() 方法不能被中断其他 onPostExecute() 方法,unitl 作业结束
    • @William Morrison,如果它是正确的,一个 onPostExecute() 方法不能被其他方法打断,为什么 Marcin Orlowski 的回答也是正确的?
    【解决方案3】:

    阅读:(复制自 android 文档here):

    首次引入时,AsyncTask 是在单个后台线程上串行执行的。从 DONUT 开始,这被更改为允许多个任务并行运行的线程池。从 HONEYCOMB 开始,任务在单线程上执行,以避免并行执行导致的常见应用程序错误。

    如果你真的想要并行执行,你可以使用 THREAD_POOL_EXECUTOR 调用 executeOnExecutor(java.util.concurrent.Executor, Object[])。

    如果您执行多个 AsyncTask,它们将同时运行如果设备是 DONUT

    如果您的设备软件是 = HONEYCOMB,则操作将按照启动顺序发布到 GUI 线程。这是因为在这些版本中,所有 AsyncTask 都将在一个后台线程上执行,因此它们不会独立执行。

    现在我想你要问的部分是:

    在所有版本中,都可以从另一个中取消一个 AsyncTask。但是,在 >=DONUT 和

    然而,两个任务不可能同时在 GUI 线程上执行,因为它是一个线程。一个 AyncTask 可能会抛出一个标志,以防止其他一些 AsyncTask 在完成后执行其 GUI 更新,但由于任务在 GUI 线程上应该是短暂的,这将是一种不好的方法。

    【讨论】:

    • 你没有得到 OP 的问题。
    • 我不同意,我认为我回答得非常充分,彻底解释了他如何做类似的事情以及为什么他试图做的事情是不可能的。
    • 我知道这些差异。这个问题是关于在 UI 线程上运行的 onPostExecute() 方法顺序。抱歉我的问题表述不好,感谢您的回答。
    • 嗯,好的。祝@CyrusSmith 好运,希望我没有进一步混淆事情!
    • @William Morrison,谢谢!不,我很清楚现在发生了什么。而您之前在其他问题中的回答让事情变得清晰。
    猜你喜欢
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多