package org.wikipedia.concurrency;

import android.os.AsyncTask;

import org.wikipedia.util.log.L;

public abstract class SaneAsyncTask<T> extends AsyncTask<Void, Void, T> {
    private Throwable thrown;

    public abstract T performTask() throws Throwable;

    public void onBeforeExecute() { }

    public void onFinish(T result) { }

    public void onCatch(Throwable caught) { }

    public void execute() {
        super.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public void cancel() {
        cancel(true);
    }

    @Override
    protected final T doInBackground(Void... voids) {
        try {
            return performTask();
        } catch (Throwable t) {
            thrown = t;
            return null;
        }
    }

    @Override
    protected final void onPostExecute(T result) {
        super.onPostExecute(result);
        if (isCancelled()) {
            return;
        }
        if (thrown != null) {
            L.i(thrown);
            onCatch(thrown);
        } else {
            try {
                onFinish(result);
            } catch (Exception e) {
                L.i(e);
                onCatch(e);
            }
        }
    }

    @Override
    protected final void onPreExecute() {
        super.onPreExecute();
        onBeforeExecute();
    }
}
@@ -62,145 +62,1512 @@
 sk;%0A
-%0Aimport org.wikipedia.util.log.L;%0A%0Apublic abstract class SaneAsyncTask%3CT%3E extends AsyncTask%3CVoid, Void, T%3E %7B%0A    private Throwable thrown
+import android.support.annotation.NonNull;%0A%0Aimport org.wikipedia.util.log.L;%0A%0Aimport java.util.concurrent.BlockingQueue;%0Aimport java.util.concurrent.Executor;%0Aimport java.util.concurrent.LinkedBlockingQueue;%0Aimport java.util.concurrent.ThreadFactory;%0Aimport java.util.concurrent.ThreadPoolExecutor;%0Aimport java.util.concurrent.TimeUnit;%0Aimport java.util.concurrent.atomic.AtomicInteger;%0A%0Apublic abstract class SaneAsyncTask%3CT%3E extends AsyncTask%3CVoid, Void, T%3E %7B%0A    private Throwable thrown;%0A%0A    // Reimplement the stock AOSP AsyncTask implementation which may differ on OEM devices.%0A    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();%0A    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;%0A    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;%0A    private static final int QUEUE_SIZE = 128;%0A    private static final int KEEP_ALIVE = 1;%0A%0A    private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() %7B%0A        private final AtomicInteger count = new AtomicInteger(1);%0A        @Override public Thread newThread(@NonNull Runnable runnable) %7B%0A            return new Thread(runnable, %22AsyncTask #%22 + count.getAndIncrement());%0A        %7D%0A    %7D;%0A%0A    private static final BlockingQueue%3CRunnable%3E POOL_WORK_QUEUE = new LinkedBlockingQueue%3C%3E(QUEUE_SIZE);%0A%0A    private static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE,%0A            MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, POOL_WORK_QUEUE, THREAD_FACTORY)
 ;%0A%0A 
@@ -1810,18 +1810,8 @@
 tor(
-AsyncTask.
 THRE
@@ -2659,8 +2659,9 @@
 %0A    %7D%0A%7D
+%0A

Reimplement AsyncTask thread pool in SaneAsyncTask