【问题标题】:Android - Simple AsyncTaskAndroid - 简单的异步任务
【发布时间】:2014-10-25 22:45:44
【问题描述】:

您好,我有一个关于 Android AsyncTask 的问题。 我在 Activity 中有一个片段。 该片段调用 AsyncTask 并在 onPostExecute() 中执行繁重的操作并更新 UI。 我的问题是这个。假设用户打开了活动。 现在片段已附加并调用 AsyncTask 的 doInBackground()。 然后用户突然按下后退按钮关闭活动。 现在,AsyncTask 线程中的执行会发生什么? 活动关闭后线程是否也会死亡? 或者我是否在onostExecute() 的开头使用isAdded() 手动检查了这个Fragment 是否仍然附加? 谢谢!

编辑

在我的 Fragment 中,我隐式声明 AsyncTask().. 像这样

            new AsyncTask<String, Void, Boolean>() {
                @Override
                protected Boolean doInBackground(String... params) {
                    return processPlays(plays);
                }

                @Override
                protected void onPostExecute(Boolean result) {
                    if (!isAdded()) return; // IS THIS FINE?
                    // UPDATE UI
                }
            }.execute();

【问题讨论】:

    标签: android android-activity android-asynctask lifecycle


    【解决方案1】:

    线程运行直到它们完成或直到 Android 系统转储内存。您的 AsyncTask 将继续运行,因此您需要检查是否无法完全取消它。否则,您会遇到这些情况,即您的应用会在您没有看到它打开的情况下崩溃。

    同样,片段可以在应用的生命周期中分离和销毁。你永远不能假设从 AsyncTask 的 doInBackground() 返回的 Fragment 或 Activity 仍然处于活动状态

    【讨论】:

    • 是的..这就是为什么我有 if(!isAdded()) return;在 onPostExecute() 的开头;请参阅随附的代码。这安全吗?
    • 是的。那是安全的。笔记。 "isAdded" 并不一定意味着 Fragment 不存在或者以后不会添加,所以还是建议不顾一切地保存 State 并在需要时更新 UI。
    【解决方案2】:

    在这种情况下,AsyncTask 线程将一直运行到最后,如果未选中,可能会在 onPostExecute() 内部崩溃。大多数情况下,您会想要取消onStop()onFinish() 甚至onPause() 上的AsyncTask(取决于您的应用程序)。

    您可以使用cancel(boolean mayInterruptIfRunning) 方法取消任务。来自Android reference

    可以通过调用 cancel(boolean) 随时取消任务。 调用此方法将导致对 isCancelled() 的后续调用 返回真。调用此方法后,onCancelled(Object) 改为 onPostExecute(Object) 将在之后调用 doInBackground(Object[]) 返回。确保任务被取消 你应该尽快检查返回值 isCancelled() 定期从 doInBackground(Object[]),如果可能的话 (例如在循环内。)

    【讨论】:

    • 问题是我的 AsyncTask 是隐式声明的......就像 new AsyncTask<..>{ ... }.execute();我运行 if(!isAdded()) return;在 onPostExecute() 的开头。这安全吗?
    • 您仍然可以在类字段中保存 AsyncTask 的引用。 asyncTask = new AsyncTask&lt;..&gt;{ ... }; asyncTask.execute(); 然后可以在任何你想要的地方打电话给asyncTask.cancel()。您所做的是安全的,但可能不是推荐的。
    猜你喜欢
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多