1

I got these kind of exception similar to AsyncTask, RejectedExecutionException and Task Limit, and "grab code and add to my package".My question is: is this the right anwser, anyone have other official solutions?

java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@416cd2e0 rejected from java.util.concurrent.ThreadPoolExecutor@4101be78[Running, pool size = 128, active threads = 128, queued tasks = 10, completed tasks = 53]

    updateTimer.schedule(updateTask, 500, 3000);

...

    updateTask = new TimerTask() {

        public void run()
        {
            updateHandler.sendMessage(msg);
        }

    };

...

    updateHandler = new Handler() {

        public void handleMessage(Message msg)
        {
            updateAsync();
        }

    };

...

    new AsyncTask<Void, Void, Void>() {

        protected Void doInBackground(Void... params)
        {
            retrieveStatus();
            return null;
        }


        protected void onPostExecute(Void result)
        {
            super.onPostExecute(result);
            updateStatusUi();// !!!?

        }

    }.execute();

    updateTask = new TimerTask() {

        public void run()
        {
                retrieveStatus();
                getActivity().runOnUiThread(new Runnable() {

                    public void run()
                    {
                        updateStatusUi();
                    }

                });
        }

    };

IN ICS: After about 10 times, it never update any more. Can you please give me a Demo, so I can pass some rigor test like: MainActivity: open(), close(), ...

P.S. myAsyncTask.executeOnExecutor(MyAsyncTask.SERIAL_EXECUTOR, [params] ); will work?

Community
  • 1
  • 1
thecr0w
  • 2,148
  • 4
  • 33
  • 59

1 Answers1

0

First, you are forking a new thread every 500ms. This is really bad, on any OS, in any programming language.

Second, you are forking yet another thread (your TimerTask), that is posting a message back to the main application thread, that is turning around and forking the AsyncTask. This is pointless.

If you are going to use a TimerTask, simply call retrieveStatus() from your run() method, then use runOnUiThread() to execute updateStatusUi() on the main application thread. Now you are only using one background thread (the TimerTask) and introducing much less overhead to accomplish the same ends.

Or, consider implementing your own ScheduledExecutorService instead of using TimerTask.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • "First, you are forking a new thread every 500ms. This is really bad, on any OS, in any programming language." Is this how google suggest to work with AsyncTask: http://developer.android.com/reference/android/os/AsyncTask.html – thecr0w Jul 28 '12 at 14:30
  • @thecr0w: You have linked to the documentation for `AsyncTask`. You will notice that they do not demonstrate starting a new `AsyncTask` every 500 milliseconds. – CommonsWare Jul 28 '12 at 14:43
  • Timer got uncautchable exception in ICS while loop my retrieveStatus() and updateStatusUi(), So ScheduledExecutorService is the unique recommended way to do that? – thecr0w Jul 28 '12 at 14:50
  • 1
    @thecr0w: You cannot call `updateStatusUi()` from a background thread. That is why, if you read my answer, I suggested that you use `runOnUiThread()` to post a `Runnable` that does the work of `updateStatusUi()`. Beyond that, since I have no real idea what the "uncautchable exception" is, I cannot help you further. – CommonsWare Jul 28 '12 at 15:06
  • I did what you say, I put updateStatusUi() in getActivity.runOnUiThread(). I will post code below and this bug really annoy me... – thecr0w Jul 28 '12 at 15:15