用于 Android 需要同步或异步执行多个异步任务,并且需要统一回调的情形。
思路很简单,通过一个队列保存异步任务,通过计数器或者从队列一个个取出来执行,实现所有任务完成后统一回调。
源码如下
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import java.util.ArrayDeque;
/**
* 用于执行多个异步任务,并且在所有任务完成后统一回调的任务类(Java 8 使用编程效率更佳)
* 使用时先实例化该类,传入监听类,然后调用 addTask() 类添加任务,最后执行 execute() 方法。
* 支持超时回调,默认超时时间5000毫秒
*/
public class MultiAsyncTask implements OnSingleTaskFinishListener {
private ArrayDeque<AsyncTask> taskQueue = new ArrayDeque<>();
private InvokeMode invokeMode;
private OnTasksFinishListener listener;
private final Object counterLock = new Object();
private final Object executeLock = new Object();
private int finishedTaskNumber = 0;
private int timeOut = 5000;
private boolean isExecuting = false;
public MultiAsyncTask(InvokeMode invokeMode, OnTasksFinishListener listener) {
this.invokeMode = invokeMode;
this.listener = listener;
}
public int getTimeOut() {
return timeOut;
}
public void setTimeOut(int timeOut) {
this.timeOut = timeOut;
}
@Override
public void onTaskFinish() {
synchronized (counterLock){
switch (invokeMode){
case SYNC:
if(taskQueue.isEmpty()){
finish();
}else{
AsyncTask task = taskQueue.pollFirst();
Thread t = new Thread(task);
t.start();
}
break;
case ASYNC:
finishedTaskNumber ++;
if(finishedTaskNumber == taskQueue.size()){
finish();
}
break;
}
}
}
@Override
public void onTimeOut() {
synchronized (executeLock) {
if (isExecuting) {
isExecuting = false;
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
listener.onTimeOut();
}
});
return;
}
} catch (ClassNotFoundException ignored) {
}
listener.onTimeOut();
}
}
}
private void finish(){
try{
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0)
{
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
listener.onFinish();
}
});
return;
}
} catch (ClassNotFoundException ignored){
}
listener.onFinish();
isExecuting = false;
}
public void addTask(AsyncTask task){
//执行任务时不允许中途添加任务
if (!isExecuting){
task.setListener(this);
task.setTimeOut(timeOut);
taskQueue.add(task);
}
}
public void execute(){
synchronized (executeLock){
isExecuting = true;
finishedTaskNumber = 0;
if(taskQueue.isEmpty()){
return;
}
switch (invokeMode){
case SYNC:
AsyncTask task = taskQueue.pollFirst();
Thread t = new Thread(task);
t.start();
break;
case ASYNC:
for(AsyncTask task1 : taskQueue){
Thread t1 = new Thread(task1);
t1.start();
}
break;
}
}
}
/**
* 单个异步任务类,需继承后实现 taskRun() 方法,并且需要在异步任务完成后调用 finishTask(), 否则不会被认为
* 任务已完成,当做超时处理
*/
public abstract static class AsyncTask implements Runnable{
private OnSingleTaskFinishListener listener;
private int timeOut = -1;
private boolean isTaskFinished = false;
public void setListener(OnSingleTaskFinishListener listener){
this.listener = listener;
}
public void setTimeOut(int timeOut) {
this.timeOut = timeOut;
}
@Override
public void run() {
taskRun();
if(timeOut != -1){
try {
Thread.sleep(timeOut);
if(!isTaskFinished){
listener.onTimeOut();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public abstract void taskRun();
/**
* 完成异步任务时调用该方法
*/
public void finishTask(){
isTaskFinished = true;
if(listener != null){
listener.onTaskFinish();
}
}
}
/**
* 执行模式,同步与异步
*/
public enum InvokeMode{
SYNC, ASYNC
}
/**
* 所有任务执行完成后回调
*/
public interface OnTasksFinishListener{
void onFinish();
void onTimeOut();
}
}
interface OnSingleTaskFinishListener{
void onTaskFinish();
void onTimeOut();
}
调用方式如下
MultiAsyncTask task = new MultiAsyncTask(MultiAsyncTask.InvokeMode.ASYNC, new MultiAsyncTask.OnTasksFinishListener() {
@Override
public void onFinish() {
ToastUtil.showShort("Bravo!!!!!");
}
@Override
public void onTimeOut() {
ToastUtil.showShort("Time Out!!!!!");
}
});
task.addTask(new MultiAsyncTask.AsyncTask(){
@Override
public void taskRun() {
//TODO do something
}
});
task.addTask(new MultiAsyncTask.AsyncTask(){
@Override
public void taskRun() {
//TODO do something
}
});
task.execute();