package com.smartandroid.sa.aysnc; import java.util.ArrayList; import java.util.LinkedList; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import android.os.Handler; import android.os.Looper; /** * the {@link TaskExecutor} can execute task in many ways. * <ul> * <li>1. OrderedTask, �����ִ��һЩ������ * <li>2. CyclicBarrierTask, ������ִ��һϵ�������һ�����������ִ�����ʱ���е�һ���ؿ��㣨ִ���ض��ĺ������� * <li>3. Delayed Task, ��ʱ���� * <li>4. Timer Runnable, ��ʱ���� * </ul> * * @author MaTianyu 2014-2-3����6:30:14 */ public class TaskExecutor { /** * �����߳� * * @param run */ public static void start(Runnable run) { AsyncTask.execute(run); } /** * �����̣߳�����������������ʱ����ʧ���� * * @param run */ public static void startAllowingLoss(Runnable run) { AsyncTask.executeAllowingLoss(run); } /** * �����첽����ִ���� * * @return */ public static OrderedTaskExecutor newOrderedExecutor() { return new OrderedTaskExecutor(); } /** * �ؿ��첽����ִ���� * * @return */ public static CyclicBarrierExecutor newCyclicBarrierExecutor() { return new CyclicBarrierExecutor(); } /** * ��ʱ�첽���� * * @param task * @param time * @param unit */ public static void startDelayedTask(final AsyncTask<?, ?, ?> task, long time, TimeUnit unit) { long delay = time; if (unit != null) delay = unit.toMillis(time); new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { task.execute(); } }, delay); } /** * ������ʱ���� * * @param run * @param delay * >0 �ӳ�ʱ�� * @param period * >0 �������ʱ�� * @return */ public static Timer startTimerTask(final Runnable run, long delay, long period) { Timer timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { run.run(); } }; timer.scheduleAtFixedRate(timerTask, delay, period); return timer; } public static class OrderedTaskExecutor { LinkedList<AsyncTask<?, ?, ?>> taskList = new LinkedList<AsyncTask<?, ?, ?>>(); private transient boolean isRunning = false; public OrderedTaskExecutor put(AsyncTask<?, ?, ?> task) { synchronized (taskList) { if (task != null) taskList.add(task); } return this; } public void start() { if (isRunning) return; isRunning = true; for (AsyncTask<?, ?, ?> each : taskList) { final AsyncTask<?, ?, ?> task = each; task.setFinishedListener(new AsyncTask.FinishedListener() { @Override public void onPostExecute() { synchronized (taskList) { executeNext(); } } @Override public void onCancelled() { synchronized (taskList) { taskList.remove(task); if (task.getStatus() == AsyncTask.Status.RUNNING) { executeNext(); } } } }); } executeNext(); } @SuppressWarnings("unchecked") private void executeNext() { AsyncTask<?, ?, ?> next = taskList.pollFirst(); if (next != null) next.execute(); else isRunning = false; } } public static class CyclicBarrierExecutor { ArrayList<AsyncTask<?, ?, ?>> taskList = new ArrayList<AsyncTask<?, ?, ?>>(); private transient boolean isRunning = false; public CyclicBarrierExecutor put(AsyncTask<?, ?, ?> task) { if (task != null) taskList.add(task); return this; } public void start(final AsyncTask<?, ?, ?> finishTask) { start(finishTask, 0, null); } @SuppressWarnings("unchecked") public void start(final AsyncTask<?, ?, ?> endOnUiTask, final long time, final TimeUnit unit) { if (isRunning) throw new RuntimeException( "CyclicBarrierExecutor only can start once."); isRunning = true; final CountDownLatch latch = new CountDownLatch(taskList.size()); new STask<Boolean>() { @Override protected Boolean doInBackground() { try { if (unit == null) latch.await(); else latch.await(time, unit); } catch (InterruptedException e) { e.printStackTrace(); } return true; } @Override protected void onPostExecute(Boolean aBoolean) { endOnUiTask.execute(); } }.execute(); startInternal(latch); } public void start(Runnable endOnUiThread) { start(endOnUiThread, 0, null); } public void start(final Runnable endOnUiThread, final long time, final TimeUnit unit) { if (isRunning) throw new RuntimeException( "CyclicBarrierExecutor only can start once."); isRunning = true; final CountDownLatch latch = new CountDownLatch(taskList.size()); new STask<Boolean>() { @Override protected Boolean doInBackground() { try { if (unit == null) latch.await(); else latch.await(time, unit); } catch (InterruptedException e) { e.printStackTrace(); } return true; } @Override protected void onPostExecute(Boolean aBoolean) { endOnUiThread.run(); } }.execute(); startInternal(latch); } private void startInternal(final CountDownLatch latch) { for (AsyncTask<?, ?, ?> each : taskList) { each.setFinishedListener(new AsyncTask.FinishedListener() { @Override public void onPostExecute() { latch.countDown(); } @Override public void onCancelled() { latch.countDown(); } }); each.execute(); } } } }