AsyncTask的doInBackground在调用AsyncTask::execute后开始执行太晚。

13
我写了一个AsyncTask,在大多数情况下,它的构造函数被调用和doInBackground被调用之间没有延迟(0毫秒延迟)。但是每当后台进行联系人同步时,我的AsyncTask的构造函数和doInBackground之间通常会出现1-3秒的延迟。在我的情况下,这种延迟是不能接受的。 我知道AsyncTask是一个后台线程,可以通过使用线程并将其优先级设置得更高来解决此问题。但是我想知道的是,如何确定是什么导致了我的AsyncTask的doInBackground没有被调用? 我使用adb shell top -m 10命令,当出现此问题时进程使用情况似乎很正常。 感谢任何帮助。

在我看来,通常情况下它会立即执行,但如果有另一个线程同时运行,就会导致它变得卡顿,因此最好检查一下你的线程并确保它们同步良好。 - Tom
3个回答

39

我之前也长期遇到过这个问题,但现在已经解决了。使用以下代码:

new AsyncTaskName().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

改为以下代码

new AsyncTaskName().execute();

它将解决在后台运行doInbackground的问题。


1
这对我非常有效。请注意,此功能是在API 11中添加的,并且警告来自:http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutorjava.util.concurrent.Executor, Params...) - Jayrox
1
需要注意的是,executeOnExecutor不能在API版本早于11的情况下使用。请参考线程https://dev59.com/kWox5IYBdhLWcg3wk1Eg#23678665。 - L. G.
这对我很有效。我只想补充一下,我们可以使用来自support-v4库的AsyncTaskCompat.executeParallel()为所有API版本执行此操作。 它处理了两种情况:从API 11+开始,我们需要手动选择THREAD_POOL_EXECUTOR,但在API 11之前,所有任务都是并行运行的。 - pratt
这难道不就是并行运行吗?它带有警告。 - miracle-doh
太棒了!在doInBackground开始之前不再有延迟。 - user25

2

通常情况下,我们不需要关心jvm的任务调度。实际上,我们也不需要去关注。

如果你的应用程序需要尽快完成某些任务,请在构造函数中完成这些任务,或者使用Asynctask的onPre方法(记住它在UI线程上执行)。

但是我同意,在Android AsyncTask的doInBackgroud调用中存在一些可疑的地方。我自己也曾经遇到过,在onPre之后doInbackground没有被调用。你可以在谷歌上搜索这个问题,很多人都遇到了这个问题。最后我选择使用传统的线程来解决问题。

我编写了自己的Asynctask,使用传统的线程作为核心,并使用Handler模拟onPre和onPost。你也可以选择这个选项。


1

区分创建和执行任务非常重要。(如您所见,ASyncTask有一个单独的execute()方法以及一个构造函数。)

创建线程可能会非常昂贵,因此您可能会发现提前创建任务,然后仅在正确的时间执行它会产生更好的结果。

如果后台操作可能经常重复,则还可以发现IntentService更适合处理单个请求的后台线程。


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