当应用程序使用列表时,在 Android 4.4 中避免 RejectedExecutionException [英] Avoiding RejectedExecutionException in Android 4.4 when app uses list

查看:32
本文介绍了当应用程序使用列表时,在 Android 4.4 中避免 RejectedExecutionException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Android 4.4 中,代码似乎发生了变化,导致使用 AsyncTasks 加载列表图标.结果是我的许多 Android 4.4 用户收到 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.

一位来自 Code Google 的聪明用户发现了这一点,并且是这样解释的:

A clever user at Code Google discovered this, and explained it in this way:

ResolverActivity 将在 Android 4.4 上抛出 RejectedExecutionException.

ResolverActivity will throw RejectedExecutionException on Android 4.4.

我查看了最新的 ResolverActivity 的代码,注意到在 ResolveListAdapter.bindView 方法中它使用了 new LoadIconTask().execute(info),这应该是根本原因.LoadIconTask 是 AsyncTask 的子类,AsyncTask 同时运行过多会导致 RejectedExecutionException.

I viewed the code of latest ResolverActivity and noticed that in ResolveListAdapter.bindView method it is using new LoadIconTask().execute(info), this should be the root cause. LoadIconTask is a subclass of AsyncTask, too many AsyncTask running at the same time will cause RejectedExecutionException.

在ResolverActivity变化可以在的Android GitHub库找到.

The ResolverActivity change can be found at the Android GitHub repo.

我的应用目前有 82 个 RejectedExecutionException 的堆栈跟踪,所有这些都是针对 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 使用不同的 Executor:

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.

使用 targetSdkVersion > 12 和更高版本代码的单独 APK,以便 HONEYCOMB_MR2 和更高版本的 Android 首选.这将导致 AsyncTask 在 HONEYCOMB_MR2 和更高版本的 Android 上使用 ThreadPool.SERIAL_EXECUTOR.

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

这篇关于当应用程序使用列表时,在 Android 4.4 中避免 RejectedExecutionException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆