package com.shizhefei.task;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.shizhefei.mvc.IAsyncDataSource;
import com.shizhefei.mvc.IDataSource;
import com.shizhefei.mvc.ProgressSender;
import com.shizhefei.mvc.RequestHandle;
import com.shizhefei.mvc.ResponseSender;
/**
* Created by luckyjayce on 2017/4/15.
*/
class TaskExecutors {
public static <DATA> TaskExecutor<DATA> create(IDataSource<DATA> dataSource, boolean isExeRefresh, ICallback<DATA> callback) {
return new SyncDataSourceExecutor<>(dataSource, isExeRefresh, callback);
}
public static <DATA> TaskExecutor<DATA> create(IAsyncDataSource<DATA> dataSource, boolean isExeRefresh, ICallback<DATA> callback) {
return new AsyncDataSourceExecutor<>(dataSource, isExeRefresh, callback);
}
public static <DATA> TaskExecutor<DATA> create(ITask<DATA> task, ICallback<DATA> callback) {
return new SyncTaskExecutor<>(task, callback);
}
public static <DATA> TaskExecutor<DATA> create(IAsyncTask<DATA> task, ICallback<DATA> callback) {
return new AsyncTaskExecutor<>(task, callback);
}
/**
* IAsyncTask和IAsyncDataSource 抽象执行类
*
* @param <DATA>
*/
private static abstract class AbsAsyncTaskExecutor<DATA> implements TaskExecutor<DATA> {
private final ISuperTask<DATA> realTask;
private ICallback<DATA> callback;
private RequestHandle requestHandle;
private TaskResponseSender<DATA> responseSender;
public AbsAsyncTaskExecutor(ISuperTask<DATA> task, ICallback<DATA> callback) {
this.realTask = task;
this.callback = callback;
if (callback == null) {
responseSender = new TaskNoCallbackResponseSender<>();
} else {
responseSender = new TaskHasCallbackResponseSender<>();
}
}
@Override
public final RequestHandle execute() {
responseSender.sendPreExecute(realTask, callback);
try {
requestHandle = executeImp(responseSender);
} catch (Exception e) {
responseSender.sendError(e);
}
return this;
}
protected abstract RequestHandle executeImp(ResponseSender<DATA> responseSender) throws Exception;
@Override
public void cancle() {
if (requestHandle != null) {
requestHandle.cancle();
}
responseSender.sendCancel();
}
@Override
public ICallback<DATA> getCallback() {
return callback;
}
@Override
public ISuperTask<DATA> getTask() {
return realTask;
}
@Override
public boolean isRunning() {
return responseSender.isRunning();
}
}
/**
* 同步task和IDataSource的抽象实现类
*
* @param <DATA>
*/
private static abstract class AbsSyncTaskExecutor<DATA> extends AsyncTask<Object, Object, DATA> implements TaskExecutor<DATA> {
private final ISuperTask<DATA> realTask;
private final TaskResponseSender<DATA> responseSender;
private ICallback<DATA> callback;
public AbsSyncTaskExecutor(ISuperTask<DATA> task, ICallback<DATA> callback) {
super();
this.callback = callback;
this.realTask = task;
if (callback == null) {
responseSender = new TaskNoCallbackResponseSender<>();
} else {
responseSender = new TaskHasCallbackResponseSender<>();
}
}
@Override
public RequestHandle execute() {
responseSender.sendPreExecute(realTask, callback);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Boolean.TRUE);
} else {
execute(Boolean.TRUE);
}
return this;
}
@Override
protected DATA doInBackground(Object... params) {
try {
return executeImp(responseSender);
} catch (Exception e) {
if (e instanceof InterruptedException) {
Log.d("TaskHelper", realTask.toString() + e);
} else {
e.printStackTrace();
}
responseSender.sendError(e);
}
return null;
}
protected abstract DATA executeImp(ProgressSender sender) throws Exception;
@Override
protected void onPostExecute(DATA result) {
super.onPostExecute(result);
responseSender.sendData(result);
}
@Override
public void cancle() {
cancelImp();
cancel(true);
responseSender.sendCancel();
}
protected abstract void cancelImp();
@Override
public boolean isRunning() {
return responseSender.isRunning();
}
@Override
public ICallback<DATA> getCallback() {
return callback;
}
@Override
public ISuperTask<DATA> getTask() {
return realTask;
}
}
/**
* IAsyncDataSource执行类
*
* @param <DATA>
*/
private static class AsyncDataSourceExecutor<DATA> extends AbsAsyncTaskExecutor<DATA> {
private final boolean isExeRefresh;
private IAsyncDataSource<DATA> dataSource;
public AsyncDataSourceExecutor(IAsyncDataSource<DATA> dataSource, boolean isExeRefresh, ICallback<DATA> callback) {
super(dataSource, callback);
this.dataSource = dataSource;
this.isExeRefresh = isExeRefresh;
}
@Override
protected RequestHandle executeImp(ResponseSender<DATA> responseSender) throws Exception {
if (isExeRefresh) {
return dataSource.refresh(responseSender);
}
return dataSource.loadMore(responseSender);
}
@Override
public boolean isExeRefresh() {
return isExeRefresh;
}
}
/**
* IAsyncTask的执行类
*
* @param <DATA>
*/
private static class AsyncTaskExecutor<DATA> extends AbsAsyncTaskExecutor<DATA> {
private IAsyncTask<DATA> task;
public AsyncTaskExecutor(IAsyncTask<DATA> task, ICallback<DATA> callback) {
super(task, callback);
this.task = task;
}
@Override
protected RequestHandle executeImp(ResponseSender<DATA> responseSender) throws Exception {
return task.execute(responseSender);
}
@Override
public boolean isExeRefresh() {
return true;
}
}
/**
* IDataSource的执行类
*
* @param <DATA>
*/
private static class SyncDataSourceExecutor<DATA> extends AbsSyncTaskExecutor<DATA> {
private final boolean isExeRefresh;
private IDataSource<DATA> task;
public SyncDataSourceExecutor(IDataSource<DATA> task, boolean isExeRefresh, ICallback<DATA> callback) {
super(task, callback);
this.task = task;
this.isExeRefresh = isExeRefresh;
}
@Override
protected DATA executeImp(ProgressSender sender) throws Exception {
if (isExeRefresh) {
return task.refresh();
}
return task.loadMore();
}
@Override
protected void cancelImp() {
}
@Override
public boolean isExeRefresh() {
return isExeRefresh;
}
}
/**
* ITask 的执行类
*
* @param <DATA>
*/
private static class SyncTaskExecutor<DATA> extends AbsSyncTaskExecutor<DATA> {
private ITask<DATA> task;
public SyncTaskExecutor(ITask<DATA> task, ICallback<DATA> callback) {
super(task, callback);
this.task = task;
}
@Override
protected DATA executeImp(ProgressSender sender) throws Exception {
return task.execute(sender);
}
@Override
protected void cancelImp() {
task.cancel();
}
@Override
public boolean isExeRefresh() {
return true;
}
}
private interface TaskResponseSender<DATA> extends ResponseSender<DATA> {
void sendCancel();
void sendPreExecute(Object realTask, ICallback<DATA> callback);
boolean isRunning();
}
private static class TaskNoCallbackResponseSender<DATA> implements TaskResponseSender<DATA> {
//isRunning可能被子线程改变值
private volatile boolean isRunning;
@Override
public void sendPreExecute(Object realTask, ICallback<DATA> callback) {
isRunning = true;
}
@Override
public boolean isRunning() {
return isRunning;
}
@Override
public void sendError(Exception exception) {
isRunning = false;
}
@Override
public void sendData(DATA data) {
isRunning = false;
}
@Override
public void sendProgress(long current, long total, Object extraData) {
}
@Override
public void sendCancel() {
isRunning = false;
}
}
private static class TaskHasCallbackResponseSender<DATA> implements TaskResponseSender<DATA> {
private Handler handler;
//callback 和 realTask 只在主线程调用
private ICallback<DATA> callback;
private Object realTask;
private boolean isRunning;
public TaskHasCallbackResponseSender() {
handler = new Handler(Looper.getMainLooper());
}
@Override
public void sendPreExecute(Object realTask, ICallback<DATA> callback) {
this.realTask = realTask;
this.callback = callback;
isRunning = true;
onPreExecute();
}
@Override
public void sendError(Exception exception) {
onPostExecute(Code.EXCEPTION, exception, null);
}
@Override
public void sendData(DATA data) {
onPostExecute(Code.SUCCESS, null, data);
}
@Override
public void sendCancel() {
onPostExecute(Code.CANCEL, null, null);
}
@Override
public void sendProgress(long current, long total, Object extraData) {
final int percent;
if (current == 0) {
percent = 0;
} else if (total == 0) {
percent = 0;
} else {
percent = (int) (100 * current / total);
}
onProgress(percent, current, total, extraData);
}
@Override
public boolean isRunning() {
return isRunning;
}
private void onPreExecute() {
if (Looper.myLooper() != Looper.getMainLooper()) {
handler.post(new Runnable() {
@Override
public void run() {
onPreExecuteMainThread();
}
});
} else {
onPreExecuteMainThread();
}
}
private void onProgress(final int percent, final long current, final long total, final Object extraData) {
if (Looper.myLooper() != Looper.getMainLooper()) {
handler.post(new Runnable() {
@Override
public void run() {
onProgressMainThread(percent, current, total, extraData);
}
});
} else {
onProgressMainThread(percent, current, total, extraData);
}
}
private void onPostExecute(final Code code, final Exception exception, final DATA data) {
if (Looper.myLooper() != Looper.getMainLooper()) {
handler.post(new Runnable() {
@Override
public void run() {
onPostExecuteMainThread(code, exception, data);
}
});
} else {
onPostExecuteMainThread(code, exception, data);
}
}
private void onPreExecuteMainThread() {
ICallback<DATA> c = callback;
if (c != null) {
c.onPreExecute(realTask);
}
}
private void onProgressMainThread(final int percent, final long current, final long total, final Object extraData) {
ICallback<DATA> c = callback;
if (c != null) {
c.onProgress(realTask, percent, current, total, extraData);
}
}
private void onPostExecuteMainThread(final Code code, final Exception exception, final DATA data) {
if (!isRunning) {
return;
}
isRunning = false;
ICallback<DATA> c = callback;
if (c != null) {
c.onPostExecute(realTask, code, exception, data);
}
realTask = null;
callback = null;
}
}
}