问题描述
在Android 4.4系统,似乎是在code,导致列表图标使用AsyncTasks加载的变化。其结果是,我的很多用户对Android 4.4系统的get RejectedExecutionException
,因为队列的大小超过限制。
In Android 4.4 there seems to be a change in the code that causes list icons to be loaded using AsyncTasks. The result is that many of my users on Android 4.4 get RejectedExecutionException
since the queue size limit is exceeded.
在 $ C $一个聪明的用户C谷歌发现这一点,并以这种方式解释它
A clever user at Code Google discovered this, and explained it in this way:
ResolverActivity将抛出RejectedExecutionException的Android 4.4系统。
该ResolverActivity变化可以在 Android的GitHub库。
The ResolverActivity change can be found at the Android GitHub repo.
我的应用程序目前对 RejectedExecutionException
82堆栈跟踪,所有这一切都为Android 4.4。栈的实例启动:
My app currently has 82 stack traces for RejectedExecutionException
, all of which are for Android 4.4. Example start of stack:
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)
...
有没有办法回避或处理这种变化?
Is there any way to sidestep or handle this change?
推荐答案
问题在于不同的执行者是AsyncTask的用途,具体取决于应用程序的targetSdkVersion:
The problem lies with the different Executors that AsyncTask uses depending on targetSdkVersion of the app:
AsyncTask.execute()使用AsyncTask.THREAD_POOL_EXECUTOR。在AsyncTask.THREAD_POOL_EXECUTOR队列被限制为128个项目。如果队列已满RejectedExecutionException被抛出。这就是发生在这里。
AsyncTask.execute() uses the AsyncTask.THREAD_POOL_EXECUTOR. The queue in AsyncTask.THREAD_POOL_EXECUTOR is limited to 128 items. If the queue is full RejectedExecutionException is thrown. This is what happens here
AsyncTask的使用AsyncTask.SERIAL_EXECUTOR。 AsyncTask.SERIAL_EXECUTOR有一个无界队列。因此,在这种情况下RejectedExecutionException从不抛出。
AsyncTask uses the AsyncTask.SERIAL_EXECUTOR. AsyncTask.SERIAL_EXECUTOR has an unbounded queue. So in this scenario RejectedExecutionException is never thrown.
使用一个单独的APK与targetSdkVersion> 12和更高的版本code所以这是preferred的HONEYCOMB_MR2和更高版本的Android系统。这将导致AsyncTask的使用ThreadPool.SERIAL_EXECUTOR上HONEYCOMB_MR2和更高的Android版本。
Use a separate APK with targetSdkVersion > 12 and a higher versionCode so that is preferred for HONEYCOMB_MR2 and later versions of Android. This will cause AsyncTask to use ThreadPool.SERIAL_EXECUTOR on HONEYCOMB_MR2 and later version of Android.
只需使用反射使AsyncTask.SERIAL_EXECUTOR默认的。
Just make AsyncTask.SERIAL_EXECUTOR the default using Reflection.
AsyncTask.class.getMethod("setDefaultExecutor", Executor.class).invoke(null, AsyncTask.SERIAL_EXECUTOR);
这篇关于避免RejectedExecutionException在Android 4.4系统,当应用程序使用清单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!