onCreateView()等待AsyncTask执行吗?

13

这是我的情况:

在我的onCreate()中,我想创建一个AsyncTask来从服务器检索数据并将其存储在ArrayList中。

然后,在我的onCreateView()中,我想把那些数据放在ListView中,设置一个onItemClickListener等等......

问题是,我正在创建一个AsyncTask和UI线程之间的竞争。如果onCreateView()AsyncTask完成检索之前被调用,则不会正确设置适配器,也不会设置onItemClickListener等......

我希望有一种方法来确保在启动onCreateView()函数之前等待AsyncTask完成执行。这有可能吗?我读到了使用任务上的get(),但我在执行它时遇到了一些麻烦。它似乎没有做任何事情。

我之所以想在onCreate()中检索数据并在onCreateView()中设置适配器(而不是在AsyncTaskonPostExecute()中设置适配器),是因为我想只检索数据一次,并且只需在用户旋转屏幕或导航回该Fragment时创建视图。

3个回答

10

以下是更好的方法。在onCreate()中初始化你的ListView并启动你的AsyncTask。一旦从服务器获取到数据,你将把它添加到与适配器相同的数组中,并调用适配器的notifyDatasetChanged()方法,该方法负责填充你的列表视图。你还可以使用ListFragment,通过调用setEmptyText()方法,添加显示在列表为空时的文本。


哦,有趣。我每次更新适配器时都需要设置setOnItemClickListener()吗?还是只需要在开始时设置一次?另外,在onCreate()中如何初始化ListView,如果视图尚未创建,那么这不会给我一个空指针异常吗? - user2085335
你只需要设置一次 OnItemClickListener。当没有数据时,只需使用一个没有元素的 ArrayList 来初始化列表视图。这样就不会出现任何空指针异常。稍后当数据到达时,你可以将其添加到同一个 ArrayList 中并调用 notifyDataSetChanged() - sujith
非常好,运行得很棒!关于OnItemClickListener的注释有一个快速问题:如果我只在onCreateView()中调用setOnItemClickListener,它似乎不起作用。但是,如果我在更新适配器后再添加另一个setOnItemClickListener调用,它就可以工作了。虽然这并不是什么大问题,但如果您有任何想法,我想知道为什么会发生这种情况。谢谢。 - user2085335
你没有展示任何代码,但是如果我要猜测的话,可能是因为你不再持有对它的引用而被垃圾回收了。你是在使用ListActivity还是ListFragment - Matt
那我是不是必须在onCreate()中填充我的View?显然我需要这个视图来找到ListView。 - tir38

1
你应该遵循@sujith的答案并更改你的实现,但这里是针对你特定问题的答案:
“我想找到一种方法,在开始onCreateView()函数之前确保我等待AsyncTask完成执行。这可能吗?”
是的,这是可能的,但它会阻止UI显示,因为它在等待任务完成。
创建和执行你的AsyncTask,然后保留对它的引用:
MyAsyncTask mTask;

...
...onCreate()
mTask = new MyAsyncTask();
mTask.execute();
...
...onCreateView()
myInfo = mTask.get();
super.onCreateView().

在您的情况下,这是一个不好的想法,但是有时您可能需要做这样的事情。
编辑:mTask.get()将返回doInBackground()返回的任何内容。

0
无论你在onCreateView()中做什么,都要将它移动到onViewCreated()中。

onViewCreated在视图准备好后被调用,所以那时就不会有问题了。


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