【问题标题】:Android java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask rejected from java.util.concurrentAndroid java.util.concurrent.RejectedExecutionException:任务 android.os.AsyncTask 从 java.util.concurrent 被拒绝
【发布时间】:2014-10-12 19:13:59
【问题描述】:

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

我在 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);
        }
    }

问题是我无法删除和取消最后一个 asynchtask 线程,这导致 rejectedExecuationException 并且不允许它在线程池大小达到时创建新线程。 请告诉我如何解决这个问题?所以我的进度条运行顺利,让我免于这个错误。

再次提醒我有一个具有列表视图的片段。

【问题讨论】:

    标签: android android-fragments android-asynctask threadpool


    【解决方案1】:

    在您的情况下,很容易得到这个例外。 ThreadPoolExecutor

    当 Executor 已关闭时,在方法 execute(Runnable) 中提交的新任务将被拒绝,并且当 Executor 对最大线程和工作队列容量都使用有限的界限并且已饱和时。

    任务拒绝导致生成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();
    }
    

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

    【讨论】:

    • 我想要连续更新,直到它达到最大值 好的,我会以某种方式管理这个。还有一件事我想问我怎样才能得到这个进度条?实际上我正在尝试但没有任何帮助。
    • 好的,我刚刚替换了行 adapter.getItem(i).setProgress();与 ((ProgressBar)(((ViewGroup) mImageGrid.getItemAtPosition(i)).getChildAt(3))).setProgress(progress);
    • 请再次检查。我已经发布了答案。
    猜你喜欢
    • 2018-02-04
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    相关资源
    最近更新 更多