package biz; import java.util.HashSet; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import android.os.Bundle; import android.util.Log; import basic.UiThreadHandler; public class iCmdExecutor { private static final String TAG = "CmdExecutor"; // private static final int CPU_COUNT = // Runtime.getRuntime().availableProcessors(); // private static final int CORE_POOL_SIZE = CPU_COUNT + 1; // private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; // private static final int KEEP_ALIVE = 1; // // private static final ThreadFactory sThreadFactory = new ThreadFactory() { // private final AtomicInteger mCount = new AtomicInteger(1); // // public Thread newThread(Runnable r) { // return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); // } // }; // // private static final BlockingQueue<Runnable> sPoolWorkQueue = // new LinkedBlockingQueue<Runnable>(128); // // /** // * An {@link Executor} that can be used to execute tasks in parallel. // */ // public static final Executor THREAD_POOL_EXECUTOR // = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, // TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); private static ExecutorService executorService = Executors .newFixedThreadPool(3); // .newCachedThreadPool();; private static final Set<iCmd> mCmds = new HashSet<iCmd>(); private static void addToPool(iCmd cmd) { Log.i(TAG, "addToPool, " + cmd); synchronized (mCmds) { mCmds.add(cmd); } } private static void removeFromPool(iCmd cmd) { Log.i(TAG, "removeFromPool, " + cmd); synchronized (mCmds) { mCmds.remove(cmd); } } public static void cancelAll(final Object tag) { if (tag == null) { throw new IllegalArgumentException( "Cannot cancelAll with a null tag"); } Log.i(TAG, "cancelAll, " + tag); synchronized (mCmds) { for (iCmd cmd : mCmds) { if (cmd.getTag() == tag) { cmd.cancel(); } } } } public static void exeAsync(final iCmd cmd, final iCmdListener listener, Object tag) { if (null == cmd) { throw new IllegalArgumentException( "Cannot exeAsync with a null cmd"); } cmd.setTag(tag); addToPool(cmd); // pre notify if (null != listener) { UiThreadHandler.post(new Runnable() { @Override public void run() { if (!cmd.isCanceled()) { Log.i(TAG, "exeAsync, listener.onPreExecute()"); listener.onPreExecute(); } else { Log.i(TAG, "exeAsync, listener.onPreExecute(), cmd is canceled"); } } }); } // do if (!cmd.isCanceled()) { executorService.submit(new CmdWrapper(cmd, listener)); } else { removeFromPool(cmd); } // post in CmdWrapper } public static void exeSync(iCmd cmd, iCmdListener listener, Object tag) { if (null == cmd) { throw new IllegalArgumentException( "Cannot exeAsync with a null cmd"); } cmd.setTag(tag); addToPool(cmd); // pre notify if (null != listener && !cmd.isCanceled()) { Log.i(TAG, "exeSync, listener.onPreExecute()"); listener.onPreExecute(); } // do exe Bundle resultBundle = null; if (!cmd.isCanceled()) { Log.i(TAG, "exeSync, cmd.exe()"); try { resultBundle = cmd.exe(); } catch (Exception e) { e.printStackTrace(); } } // post notify if (null != listener && !cmd.isCanceled()) { Log.i(TAG, "exeSync, listener.onPostExecute()"); listener.onPostExecute(resultBundle); } removeFromPool(cmd); } private static class CmdWrapper extends FutureTask<Bundle> { private iCmdListener listener; private iCmd cmd; public CmdWrapper(iCmd cmd, iCmdListener listener) { super(new CmdCallable(cmd)); this.listener = listener; this.cmd = cmd; } @Override protected void done() { Log.i(TAG, "CmdWrapper, done, tid=" + Thread.currentThread().getId()); removeFromPool(cmd); boolean errorOccured = false; try { final Bundle resultBundle = get(); UiThreadHandler.post(new Runnable() { @Override public void run() { if (!cmd.isCanceled()) { Log.i(TAG, "CmdWrapper, done, listener.onPostExecute(resultBundle), tid=" + Thread.currentThread().getId()); listener.onPostExecute(resultBundle); } } }); } catch (CancellationException e) { errorOccured = true; e.printStackTrace(); } catch (InterruptedException e) { errorOccured = true; e.printStackTrace(); } catch (ExecutionException e) { errorOccured = true; e.printStackTrace(); } if (errorOccured) { UiThreadHandler.post(new Runnable() { @Override public void run() { if (!cmd.isCanceled()) { Log.i(TAG, "CmdWrapper, done, listener.onPostExecute(null)"); listener.onPostExecute(null); } } }); } } private static class CmdCallable implements Callable<Bundle> { private iCmd cmd; public CmdCallable(iCmd cmd) { this.cmd = cmd; } @Override public Bundle call() throws Exception { if (!cmd.isCanceled()) { try { Log.i(TAG, "CmdCallable, call, cmd.exe(), tid=" + Thread.currentThread().getId()); return cmd.exe(); } catch (Exception e) { } } return null; } } } }