在Android 4.4中,似乎有一个代码变化导致列表图标使用AsyncTasks加载。结果是我的许多Android 4.4用户会因为超过队列大小限制而收到RejectedExecutionException错误。Code Google上的一位聪明用户发现了这一点,并以以下方式解释:
ResolverActivity在Android 4.4上会抛出RejectedExecutionException异常。
我查看了最新的ResolverActivity代码,并注意到在ResolveListAdapter.bindView方法中它使用new LoadIconTask().execute(info),这应该是根本原因。LoadIconTask是AsyncTask的子类,同时运行太多的AsyncTask将导致RejectedExecutionException异常。
ResolverActivity的更改可以在Android GitHub repo上找到。
ResolverActivity在Android 4.4上会抛出RejectedExecutionException异常。
我查看了最新的ResolverActivity代码,并注意到在ResolveListAdapter.bindView方法中它使用new LoadIconTask().execute(info),这应该是根本原因。LoadIconTask是AsyncTask的子类,同时运行太多的AsyncTask将导致RejectedExecutionException异常。
ResolverActivity的更改可以在Android GitHub repo上找到。
我的应用程序目前有82个RejectedExecutionException
堆栈跟踪,所有这些都是针对Android 4.4的。堆栈跟踪的示例开始:
java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@41d44580 rejected from java.util.concurrent.ThreadPoolExecutor@41a575c0[Running, pool size = 5, active threads = 5, queued tasks = 128, completed tasks = 140]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2011)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:793)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1339)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:590)
at android.os.AsyncTask.execute(AsyncTask.java:535)
at com.android.internal.app.ResolverActivity$ResolveListAdapter.bindView(ResolverActivity.java:716)
at com.android.internal.app.ResolverActivity$ResolveListAdapter.getView(ResolverActivity.java:702)
at android.widget.AbsListView.obtainView(AbsListView.java:2255)
...
有没有什么方法可以规避或处理这个变化?
AsyncTask.execute()
文档中有说明。基本上使用SERIAL_EXECUTOR是更安全的默认选项,因为它会导致较少难以重现的线程问题,所以他们转而使用它。不,我认为你切换到SERIAL_EXECUTOR不会破坏任何东西。 - HHK