gpt4 book ai didi

Android java.util.concurrent.RejectedExecutionException : Task android. os.AsyncTask 被 java.util.concurrent 拒绝

转载 作者:搜寻专家 更新时间:2023-11-01 07:57:50 29 4
gpt4 key购买 nike

我正在 listview 的线程池上创建异步任务。我正在通过 asynchtask 的 listarray 处理这些任务。当 fragment 被销毁时我必须删除这些任务,并且当我在销毁最后一个 fragment 后制作新 fragment 时必须再次分配这些任务。

我在 ListView 适配器中的代码是

if(FragmentNowPlaying.task.isEmpty()){
FragmentNowPlaying.task.add( new ProgressAsynchTask(holder.info,tvShows, position));
FragmentNowPlaying.task.get(position).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else if(position >= FragmentNowPlaying.task.size()){
FragmentNowPlaying.task.add( new ProgressAsynchTask(holder.info,tvShows, position));
FragmentNowPlaying.task.get(position).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else if(position < FragmentNowPlaying.task.size()){

if(FragmentNowPlaying.task.get(position).getStatus().RUNNING == null){
FragmentNowPlaying.task.remove(position);
FragmentNowPlaying.task.add( new ProgressAsynchTask(holder.info,tvShows, position));
FragmentNowPlaying.task.get(position).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else if(FragmentNowPlaying.task.get(position).getStatus().RUNNING != null){

FragmentNowPlaying.task.get(position).cancel(true);
FragmentNowPlaying.task.remove(position);
FragmentNowPlaying.task.add( new ProgressAsynchTask(holder.info,tvShows, position));
FragmentNowPlaying.task.get(FragmentNowPlaying.task.size()-1).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}

问题是我无法删除和取消最后一个异步任务线程,这会导致 rejectedExecuationException 并且不允许它在线程池大小达到时创建新线程。请告诉我如何解决这个问题?这样我的进度条就可以顺利运行,从而避免了这个错误。

再次提醒我有一个带有 ListView 的 fragment 。

最佳答案

在您的情况下,很容易获得此异常。 ThreadPoolExecutor

New tasks submitted in method execute(Runnable) will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated.

任务拒绝导致生成 RejectedExecutionException .在您的情况下,已达到最大线程数。线程和任务限制取决于 Android 平台版本,例如 Android 4.0.1 MAXIMUM_POOL_SIZE = 128。

这就是为什么即使您具有示例中的逻辑,也很容易达到列表中 128 项的线程限制,尤其是在运行时间较长的任务时。

我不认为更新列表中的进度条需要每个列表项单独的线程。从我的角度来看,一个 Thread 或 AsyncTask 就足以完成这项工作。没有足够的代码来进行适当的重构,但最简单的概念如下:

Handler uiHandler = new Handler(Looper.getMainLooper());

//Somewhere in your activity

Thread updateThread = new Thread(){
@Override
public void run() {
while(!isInterrupted()){
final Map<Integer, Integer> progressStates = getCurrentProgress();
uiHandler.post(new Runnable() {
@Override
public void run() {
for (int i = 0; i < adapter.getCount(); i++) {
int progress = progressStates.get(i);
adapter.getItem(i).setProgress();//It's not default method you need to implement it in your item
}
adapter.notifyDataSetChanged();
}
});
try {
sleep(1000); //Schedule next update in 1 second
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

private Map getCurrentProgress(){
//do long running operation here
...
return progresStates;
}
}.start();

//Don't forget stop this thread if user gone from screen. For example in your activity
public void onDestroy(){
updateThread.interrupt();
}

如果您确实有计算进度的特殊线程(例如玩家线程),则无需启动新线程,只需从该线程更新进度即可。

关于Android java.util.concurrent.RejectedExecutionException : Task android. os.AsyncTask 被 java.util.concurrent 拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25387614/

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