【问题标题】:Creating another AsyncTask inside of doInBackground在 doInBackground 中创建另一个 AsyncTask
【发布时间】:2013-03-27 11:11:10
【问题描述】:

我最近查看了 SO 以找到答案 to the same question here,但没有针对这样做的风险问题的答案。但基本上我想在另一个AsyncTaskdoInBackground() 方法中运行另一个AsyncTask。这是一种不好的方法和/或是否会留下任何潜在的副作用?

我知道在onPostExecute() 中运行它是有效的,从过去的经验来看,我没有遇到任何问题,因为onPostExecute() 运行在以AsyncTask 开头的主线程上。

【问题讨论】:

    标签: java android asynchronous android-asynctask


    【解决方案1】:

    来自 API 文档:

    •任务实例必须在 UI 线程上创建。

    doInBackground() 在后台线程上运行。所以你不能从 doInBackground() 创建和运行另一个异步任务。

    http://developer.android.com/reference/android/os/AsyncTask。查看线程规则下的主题。

    当一个异步任务被执行时,该任务会经过 4 个步骤:(直接来自文档)

    1.onPreExecute(),在任务执行之前在 UI 线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。

    2.doInBackground(Params...),在 onPreExecute() 执行完成后立即在后台线程调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数传递到这一步。计算的结果必须由这一步返回,并将传递回最后一步。此步骤还可以使用 publishProgress(Progress...) 来发布一个或多个进度单位。这些值在 UI 线程的 onProgressUpdate(Progress...) 步骤中发布。

    3.onProgressUpdate(Progress...),在调用 publishProgress(Progress...) 后在 UI 线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时在用户界面中显示任何形式的进度。例如,它可用于动画进度条或在文本字段中显示日志。

    4.onPostExecute(Result),在后台计算完成后在 UI 线程上调用。后台计算的结果作为参数传递给这一步。

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

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

    您也可以考虑使用替代 RoboSpicehttps://github.com/octo-online/robospice

    可以提出多个香料请求。任务完成时在 ui 线程上通知。值得一看 robospice。

    【讨论】:

    • 非常好的和彻底的响应以及多种选择。再次感谢 Raghunandan
    • +1 以获得如此全面的答案。我有兴趣阅读The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.(来自文档)-您知道自动完成了什么吗?
    • @David Caunt 检查链接stackoverflow.com/questions/14978924/…
    • @Nate 检查线程规则developer.android.com/reference/android/os/AsyncTask.html。类加载和执行(Params...) 必须在 UI 线程上调用。我认为它与我在答案中发布的链接相同,我只是从文档中引用它
    • @Nate 你能编辑那部分吗?我猜这个词组加载是误导
    【解决方案2】:

    AsyncTask(),除了 Honeycomb 版本,串行执行。所以,不,你不能在 doInBackground() 中执行另一个 AsyncTask() —— 我想我应该说我从未尝试过,但你不太可能达到预期的效果。

    我询问了在某个 Google 办公时间执行 AsyncTask() 的情况。当被问到“为什么它从串行变为并行并返回到串行执行?”时,他们直截了当地说; “因为它破坏了很多东西。”

    【讨论】:

    • 这并不完全正确。执行方法在默认执行器上执行任务,正如您所说,它恰好是自 Honeycomb 以来的单线程(串行)执行器。但是您可以使用executeOnExecutor 在您自己的执行器上执行任务。这适用于可以安全地并行执行的任务。
    • @DavidCaunt 100% 正确。 +1 只是想保持简单:)
    猜你喜欢
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多