0

i'm getting a RejectedExecutionException when i call executeOnExecutor() in my adapter but this happens only in this case: the app is runned on devices with a very large screen like a Nexus 10 for example and not with smaller ones and also only in the case in which the screen is in portrait (not landscape) mode in the class in which adapter is called.

This is my adapter code:

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

This is my 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)
Giorgio Antonioli
  • 15,771
  • 10
  • 45
  • 70

1 Answers1

1

You are starting too many AsyncTask instances. On that device, with a quad-core CPU, at most 9 tasks will run at one time, and the work queue offers an additional 128 slots. You have attempted to spawn a 138th item in parallel.

Rework your code to use fewer simultaneous AsyncTask instances. Or, use your own custom Executor with executeOnExecutor().

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I'm pretty sure that i can't avoid to run all those tasks for what i want to obtain, but now i'll documentate a bit about a custom Executor. – Giorgio Antonioli Mar 18 '15 at 19:23
  • @Fondesa: "I'm pretty sure that i can't avoid to run all those tasks for what i want to obtain" -- are you showing 138 `ListView` rows at once? If not, then you do not need 138 simultaneous tasks. If the user flings the list, are you really going to do thousands of rows of I/O before getting to the rows that are presently visible? Libraries like Picasso know to cancel tasks if the row has been recycled; you will need to implement the same logic. – CommonsWare Mar 18 '15 at 19:30
  • Oh ok, i'll documentate about it, thanks for your help! P.s. i'm not showing 138 ListView rows at once so i have to fix my code, thanks! – Giorgio Antonioli Mar 18 '15 at 19:32
  • Sorry if i write again but that's why i love CommonsWare, i followed your idea and your answer here: http://stackoverflow.com/questions/4748964/android-cancel-asynctask-forcefully and now with some changes it works perfectly using only 15 slots. – Giorgio Antonioli Mar 18 '15 at 20:05