Android AsyncTask - 为什么doInBackground()没有执行?

6

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

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(),则第二次就可以正常工作。但是为什么execute()无效呢?AsyncTask的生命周期是否与片段绑定或者其他原因呢?
提前感谢!

我不确定,但是Fragment可以有UI组件,所以在后台线程中操作它们时要小心。您是否尝试将日志语句放在“doInBackground”方法的第一行并查看其是否显示? - kabuko
是的,我做到了。第一次尝试时,onPreExecute()和doInBackground()都被调用,但第二次只调用了onPreExecute() :( - user2062024
当你使用executeOnExecutor时,我猜想你正在使用的是THREAD_POOL_EXECUTOR而不是SERIAL_EXECUTOR,对吧?尝试一下使用SERIAL_EXECUTOR,我敢打赌你会得到相同的(不希望出现的)结果。 - kabuko
是的,使用 SERIAL_EXECUTOR 跟使用 execute() 一样会得到相同的结果。但是似乎在 AsyncTask 线程上有些问题,但是不知道为什么...因为在第一次运行时,onPostExecute() 就被调用了,没有任何问题! - user2062024
2个回答

1
我觉得问题可能出现在AsyncTask中。在现代版本的Android中,AsyncTask默认只在一个线程上运行,除非您指定了一个多线程的Executor。由于onPreExecute()在主线程上运行,所以它仍然可以成功运行。但是第二次您永远不会看到doInBackground,因为单个后台线程仍然停留在第一次调用时。您需要检查LocalKeekLauncherFragment.setFragment(fragment)的内容,以确定导致程序挂起的原因。

实际上,这两行片段转换代码应该在onPostExecute()中。我已经编辑了代码。但是,在第一次尝试时,onPreExecute()、doInBackground()和onPostExecute()都会运行。而在第二次尝试时,只有onPreExecute()会运行。如果onPostExecute()在第一次尝试时运行,那么AsyncTask第一次并没有挂起,对吗? - user2062024
我同意你的看法,我的AsyncTask被阻塞了,因为我发现在第二次运行后,所有其他部分中的AsyncTask.execute()都停止工作了。 - user2062024
在执行asyncTask之前,我检查了它的状态,在第二次尝试时看起来很好。 - user2062024
关于onPostExecute,你说得很好,但我仍然怀疑是后台线程中的某些东西导致了这个停顿。你能贴出//DO SOMETHING的代码吗? - kabuko

0

看起来doInBackground线程可能已经第二次崩溃了。它不能在第一次尝试时保持卡住状态,因为onPostExecute被调用,只有当doInBackground成功返回值时才可能发生这种情况。


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