gpt4 book ai didi

android - 当应用程序使用列表时避免 Android 4.4 中的 RejectedExecutionException

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:36:42 24 4
gpt4 key购买 nike

在 Android 4.4 中,代码似乎发生了变化,导致使用 AsyncTasks 加载列表图标。结果是我的许多 Android 4.4 用户都收到 RejectedExecutionException,因为超出了队列大小限制。

一个聪明的用户 Code Google发现了这一点,并以这种方式解释:

ResolverActivity will throw RejectedExecutionException on Android 4.4.

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.

可以在 Android GitHub repo 中找到 ResolverActivity 更改.

我的应用目前有 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 根据应用的 targetSdkVersion 使用不同的执行器:

1) targetSdkVersion <= 12

AsyncTask.execute() 使用 AsyncTask.THREAD_POOL_EXECUTOR。 AsyncTask.THREAD_POOL_EXECUTOR 中的队列限制为 128 个项目。如果队列已满,则抛出 RejectedExecutionException。这是这里发生的事情

2) targetSdkVersion > 12

AsyncTask 使用 AsyncTask.SERIAL_EXECUTOR。 AsyncTask.SERIAL_EXECUTOR 有一个无界队列。所以在这种情况下,永远不会抛出 RejectedExecutionException。

解决方案 1(也称为“干净”解决方案)

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

解决方案 2(又名肮脏的 hack)

只需使用反射将 AsyncTask.SERIAL_EXECUTOR 设置为默认值即可。

AsyncTask.class.getMethod("setDefaultExecutor", Executor.class).invoke(null, AsyncTask.SERIAL_EXECUTOR);

关于android - 当应用程序使用列表时避免 Android 4.4 中的 RejectedExecutionException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24343563/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com