Android - Priority scheduling with AsyncTask's THREAD_POOL_EXECUTOR

    AsyncTask's THREAD_POOL_EXECUTOR gives application an ability to execute tasks simultaneously limited by the number of threads in the pool. Any new request that can't be serviced immediately is queued and considered on a FIFO basis. This might seem fine for most applications but few might want to prioritize certain tasks based on user interaction.

   One might be tempted to use a custom ThreadPoolExecutor managing a PriorityBlockingQueue,

   public final AsyncTask<Params, Progress, Result> executeOnExecutor (Executor exec, Params... params)

   Sadly, this approach fails half way as the actual Runnable object type submitted to the executor is internal within AsyncTask and isn't exposed to facilitate comparison via Comparator.

        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);

                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
                return postResult(doInBackground(mParams));
            }
        };

        mFuture = new FutureTask<Result>(mWorker) {
            @Override
            protected void done() {
                try {
                    postResultIfNotInvoked(get());
                } catch (InterruptedException e) {
                    android.util.Log.w(LOG_TAG, e);
                } catch (ExecutionException e) {
                    throw new RuntimeException("An error occured while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };

   Besides, there isn't any way to associate executed async tasks with these Runnable objects. This kind of defeats the point of supporting custom ThreadPoolExecutor by AsyncTask.

   The only workaround is to fork a version of AsyncTask and implement the required functionality. One such implementation called PriorityAsyncTask is available here and saves the day.

No comments: