【问题标题】:Android AsyncTask - why is doInBackground() not executed?Android AsyncTask - 为什么不执行 doInBackground()?
【发布时间】:2013-08-21 20:09:53
【问题描述】:

我有一个包含以下方法的嵌套片段:

public void onSave() {
    if (getActivity() == null || view == null) return;
    if (file != null && file.exists()) {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected void onPreExecute() {
                Log.d("log", "onPreExecute of save ex");
            }

            @Override
            protected Void doInBackground(Void... params) {

                Log.d("log", "doInBackground of save ex");
                //DO SOMETHING
                return null;
            }

            protected void onPostExecute(Void result) {
                BaseFragment fragment = new LocalListFragment();
                ((LocalLauncherFragment)(LocalEditFragment.this.getParentFragment())).setFragment(fragment);
                Log.d("log", "end of save ex");
            };
        }.execute();
    } else {
        showAlert();
    }
}

我的问题是如果我第一次调用这个方法,它会一直执行到onPostExecute()。但是,如果我去其他片段并新打开这个片段(通过创建一个新的片段对象并替换它),那么只有 onPreExecute() 被执行。为什么这个 asyncTask 对象第二次没有很好地执行?

有趣的是,如果我使用 executeOnExecutor() 那么它第二次就可以正常工作了。但是为什么不执行()工作? AsyncTask 的生命与片段或其他东西有关吗?

提前致谢!

【问题讨论】:

  • 我对此并不确定,但 Fragments 可以有 UI 组件,所以我会小心在后台线程中搞乱它们。您是否尝试过将您的日志语句作为doInBackground 方法的第一行并查看它是否显示?
  • 是的,我做到了。在第一次尝试时,都调用了 onPreExecute() doInBackground() 但在第二次时,只调用了 onPReExecute() :(
  • 当您使用executeOnExecutor 时,我猜您使用的是THREAD_POOL_EXECUTOR 而不是SERIAL_EXECUTOR,对吧?尝试使用SERIAL_EXECUTOR,我敢打赌你会得到相同的(不需要的)行为。
  • 是的,使用 SERIAL_EXECUTOR 给我的结果与使用 execute() 相同。有些东西似乎真的挂在 AsyncTask 线程上,但无法弄清楚为什么......因为在第一次运行时,onPostExecute() 被调用而没有任何问题!

标签: android android-asynctask fragment


【解决方案1】:

在我看来,AsyncTask 中挂着什么东西。在现代版本的 Android 中,AsyncTasks 在单线程上运行,除非您指定多线程的 ExecutoronPreExecute() 仍然成功运行,因为它在主线程上运行。你第二次看不到doInBackground,因为单个后台线程仍然挂在第一次调用中。您需要检查 LocalKeekLauncherFragment.setFragment(fragment) 的内容以了解导致挂起的原因。

【讨论】:

  • 其实那两行片段过渡应该在onPostExecute()中。我编辑了代码代码。仍然......在第一次尝试时,onPreExecute()、doInBackgroiund()、onPostExecute() 运行。在第二次尝试时,只有 onPreExecute() 运行。如果 onPostExecute() 在第一次尝试时运行,则意味着 AsyncTask 在第一次尝试时没有挂起,不是吗?
  • 我同意你的观点,我的 AsyncTask 被阻止了,因为我发现在我第二次运行之后,AsyncTask.execute() 的所有其他部分都停止了工作。
  • 我在执行 asyncTask 之前检查了它的状态,第二次尝试它似乎很好..
  • 这是关于onPostExecute 的一个好点,但我仍然怀疑是什么原因导致后台线程挂起。你能把//DO SOMETHING的代码贴出来吗?
【解决方案2】:

看来 doInBackground 线程可能已经第二次崩溃了。它不能从第一次尝试就卡住,因为 onPostExecute 被调用,这只有在 doInBackground 成功返回值时才有可能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多