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();
}
}
}
}