【问题标题】:java.util.concurrent.RejectedExecutionException with Thread Pool Executorjava.util.concurrent.RejectedExecutionException 与线程池执行器
【发布时间】:2015-03-18 19:16:58
【问题描述】:

当我在适配器中调用 executeOnExecutor() 时,我收到了 RejectedExecutionException,但这仅在这种情况下发生: 该应用程序在具有非常大屏幕(例如 Nexus 10)的设备上运行,而不是在较小的设备上运行,并且仅在调用适配器的类中屏幕处于纵向(非横向)模式的情况下。

这是我的适配器代码:

public class HomeListAdapter extends ArrayAdapter<Manga> {
    Gson gson;
    private final Context context;
    private List<Manga> list;

    public HomeListAdapter(Context context, List<Manga> list) {
        super(context, R.layout.homelistadapter, list);

        this.context = context;
        this.list = list;
        gson = new Gson();
    }

    static class ViewHolder{
        TextView tvTitle;
        TextView tvChapter;
        TextView tvDate;
        ImageView immagine;
        int position;
    }

    @Override
    public View getView(final int position, View rowView, ViewGroup parent) {
        final ViewHolder viewHolder;

        if(rowView==null){
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowView = inflater.inflate(R.layout.homelistadapter, parent, false);

            viewHolder = new ViewHolder();

            viewHolder.tvTitle = (TextView) rowView.findViewById(R.id.tvTitle);
            viewHolder.tvChapter = (TextView) rowView.findViewById(R.id.tvChapter);
            viewHolder.tvDate = (TextView) rowView.findViewById(R.id.tvDate);
            viewHolder.immagine = (ImageView) rowView.findViewById(R.id.imageView);

            rowView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) rowView.getTag();
        }

        viewHolder.position = position;

        //HERE is where i'm getting the exception only on largest screens

        new AsyncList(viewHolder, position).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "url");

        return rowView;
    }

    private class AsyncList extends AsyncTask<String, Void, MangaSpec> {
        private ViewHolder holder;
        private int position;
        public AsyncList(ViewHolder viewholder, int position){
            this.holder = viewholder;
            this.position = position;
        }

        @Override
        protected MangaSpec doInBackground(String... params) {
            String urlManga = null;
            try {
                urlManga = MainActivity.connessione(params[0]);
            } catch (Exception e) {
                e.printStackTrace();
            }
            assert urlManga != null;
            return gson.fromJson(urlManga.trim(), MangaSpec.class);
        }

        @Override
        protected void onPostExecute(MangaSpec manga) {
            super.onPostExecute(manga);

            if(holder.position == position){
                holder.tvTitle.setText(list.get(position).getT());
                holder.tvTitle.setSelected(true);

                if(Integer.parseInt(String.valueOf(list.get(position).getS()))==2)
                    holder.immagine.setImageResource(R.drawable.book_close);

                List generic = manga.getChapters();

                List chapters = (List) generic.get(0);
                double numero = (Double) chapters.get(0);
                String titoloC = (String) chapters.get(2);

                if((numero-(int)numero)!=0)
                    holder.tvChapter.setText(numero+" - "+titoloC);
                else
                    holder.tvChapter.setText((int)numero+" - "+titoloC);

                holder.tvChapter.setSelected(true);

                double a = ((Number) chapters.get(1)).doubleValue();

                Date date = new Date((long) (a*1000));
                String formattedDate = new SimpleDateFormat("HH:mm - dd/MM/yy").format(date);

                holder.tvDate.setText(formattedDate);
            }
        }
    }
}

这是我的 LogCat:

java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@331ef9b7 rejected from java.util.concurrent.ThreadPoolExecutor@ed04524[Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 245]
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 com.example.giorgio.mangaproject.HomeListAdapter.getView(HomeListAdapter.java:61)
at android.widget.AbsListView.obtainView(AbsListView.java:2344)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
at android.widget.ListView.onMeasure(ListView.java:1182)
at android.view.View.measure(View.java:17430)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:727)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:463)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17430)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:868)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:453)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2560)
at android.view.View.measure(View.java:17430)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

【问题讨论】:

    标签: android multithreading asynchronous threadpoolexecutor


    【解决方案1】:

    您正在启动太多AsyncTask 实例。在该设备上,使用四核 CPU,一次最多可以运行 9 个任务,并且工作队列提供了额外的 128 个插槽。您已尝试并行生成第 138 个项目。

    重新编写代码以使用更少的并发 AsyncTask 实例。或者,使用您自己的自定义 ExecutorexecuteOnExecutor()

    【讨论】:

    • 我很确定我无法避免为我想要获得的东西运行所有这些任务,但现在我将记录一些关于自定义执行器的信息。
    • @Fondesa:“我很确定我无法避免为我想要获得的东西运行所有这些任务”——您是否一次显示 138 个ListView 行?如果没有,那么您不需要 138 个并发任务。如果用户扔掉列表,你真的会在获得当前可见的行之前执行数千行 I/O 吗?如果行已被回收,像 Picasso 这样的图书馆知道取消任务;您将需要实现相同的逻辑。
    • 哦,好的,我会记录一下,感谢您的帮助!附:我没有一次显示 138 个 ListView 行,所以我必须修复我的代码,谢谢!
    • 对不起,如果我再写一次,但这就是我喜欢 CommonsWare 的原因,我在这里遵循了您的想法和答案:stackoverflow.com/questions/4748964/…,现在经过一些更改,它仅使用 15 个插槽即可完美运行。
    猜你喜欢
    • 2023-03-18
    • 2014-08-27
    • 2017-12-29
    • 2021-04-11
    • 1970-01-01
    • 2018-07-28
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多