AsyncTask, RejectedExecutionException and Task Lim

2019-01-09 09:19发布

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]

5条回答
放我归山
2楼-- · 2019-01-09 09:58

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:

private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(128);

In my opinion that limit makes absolutely no sense at all and AsyncTask.SERIAL_EXECUTOR has an unlimited queue.

查看更多
干净又极端
3楼-- · 2019-01-09 10:01

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?

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 using AsyncTask.

Is there a way to increase this limit?

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.

Is it safe to just ignore this exception?

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.

查看更多
Rolldiameter
4楼-- · 2019-01-09 10:02

"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.

查看更多
祖国的老花朵
5楼-- · 2019-01-09 10:10

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.

查看更多
爷的心禁止访问
6楼-- · 2019-01-09 10:11

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] );

查看更多
登录 后发表回答