AsyncTask、RejectedExecutionException 和任务限制
我正在使用 AsyncTask 从远程服务器获取大量缩略图并在网格视图中显示它们。问题是,我的网格视图一次显示 20 个缩略图,因此创建 20 个 AsyncTasks 并启动 20 次执行,每个缩略图一次。
我的代码中出现 RejectedExecution
异常。我记得在某处读过,AsyncTask 一次可以在其队列中拥有的任务数量是有限的,我可能会遇到这个问题。这个栏被取消了吗?
有没有办法提高这个限制?忽略此异常是否安全?(通过使用空的 catch(RejectedException e){}
块?)
我在 Android 1.6 模拟器上运行此代码,并且代码中的 API 级别(minSDKVersion 为3)。 [编辑:添加了 SDK 和 API 级别信息]
I am fetching lots of thumbnails from a remote server and displaying them in a grid view, using AsyncTask. The problem is, my grid view displays 20 thumbnails at a time, so that creates 20 AsyncTasks and starts 20 executes, one per thumbnail.
I get RejectedExecution
exception in my code. I recall reading somewhere that there is a limit to number of tasks that AsyncTask can have in its queue at a time, i might be hitting that. Was this bar lifted?
Is there a way to increase this limit? Is it safe to just ignore this exception?(by having an empty catch(RejectedException e){}
block?)
I am running this code on Android 1.6 emulator and the API level in my code(minSDKVersion is 3).
[EDIT: Added SDK and API level info]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
AsyncTask
目前似乎支持 10 个线程和 10 个工作队列深度。理论上,这只支持 20 个项目......如果没有其他东西使用AsyncTask
。获取源代码,修改它,将其放入您自己的包中,然后使用该包。我用我的
AsyncTaskEx
做到了这一点,尽管这是基于 Android 的1.5 来源。您的工作不会排队等待执行。这是否“安全”取决于您。我不知道对
AsyncTask
基础设施有任何其他影响。AsyncTask
appears to presently support 10 threads and a work queue depth of 10. In theory, that would just support 20 items...if nothing else is usingAsyncTask
.Grab the source code, modify it, put it in your own package, and use that one. I did this with my
AsyncTaskEx
, though that is based on the Android 1.5 source.Your work will not be queued for execution. Whether that is "safe" is up to you. I am not aware of any other impacts on the
AsyncTask
infrastructure.我自己在应用程序中也做过同样的事情。
对我来说,一次启动 20 个并行线程来从服务器下载缩略图并将其推送到数据适配器听起来不是一个好主意。所有这些线程只会互相绊倒并互相妨碍。
相反,我将只启动一个线程,让它循环收集缩略图,并在它们到达时将它们添加到适配器中。
I've done this exact same thing myself in an application.
Launching 20 parallel threads at once to download thumbnails from a server and push them to a data adapter doesn't sound like a good idea to me. All those threads will just trip all over each other and get in each other's way.
Instead, I would launch just one thread, have it collect the thumbnails in a loop, and add them to the adapter as they arrive.
您可以将串行执行器与 AsyncTask.executeOnExecutor 一起使用来序列化您的任务,但这会将任务限制为一次只能有一个并发任务。获取缩略图时可能会很好:
myAsyncTask.executeOnExecutor(MyAsyncTask.SERIAL_EXECUTOR, [params] );
You could use the serial executor with AsyncTask.executeOnExecutor, to serialize your tasks, but that will limit the task to only one concurrent task at the time. Might be good though when getting thumbnails:
myAsyncTask.executeOnExecutor(MyAsyncTask.SERIAL_EXECUTOR, [params] );
问题在于,
AsyncTask.THREAD_POOL_EXECUTOR
的待处理 AsyncTask 数量为 128。队列填满后,就无法对新的 AsyncTask 进行排队。来自 AsyncTask 源代码:
在我看来,限制完全没有意义,并且
AsyncTask.SERIAL_EXECUTOR
有一个无限的队列。The problem is that the number of pending AsyncTasks for
AsyncTask.THREAD_POOL_EXECUTOR
is 128. Once the queue is filled up no new AsyncTasks can be queued.From AsyncTask source code:
In my opinion that limit makes absolutely no sense at all and
AsyncTask.SERIAL_EXECUTOR
has an unlimited queue.“安全”地忽略 - 您需要确保当您捕获错误时,您计划在执行后执行的任何类型的通知都将在此处完成 - 否则,如果您的其他代码做出以下假设,您可能会留下一些悬而未决的东西收到此任务的回复。
"Safe" to ignore - You need to make sure that any kind of notification that you were planning to do in the post-execute will be done here when you catch the error - otherwise you might leave something hanging if your other code makes assumptions about hearing back from this task.