package com.dwdesign.tweetings.util;
import java.util.concurrent.ExecutorService;
import android.os.Handler;
public abstract class AsyncTask<Param, Progress, Result> {
private Thread mThread;
private final Handler mHandler;
private final ExecutorService mExecutor;
private final Runnable mRunnable;
private boolean mCancelled;
private Param[] mParams;
private Status mStatus = Status.PENDING;
public AsyncTask() {
this(new Handler(), null);
}
public AsyncTask(final ExecutorService executor) {
this(new Handler(), executor);
}
public AsyncTask(final Handler handler) {
this(handler, null);
}
public AsyncTask(final Handler handler, final ExecutorService executor) {
if (handler == null) throw new NullPointerException();
mHandler = handler;
mExecutor = executor;
mRunnable = new BackgroundRunnable();
}
public void cancel(final boolean mayInterruptIfRunning) {
mCancelled = true;
if (mExecutor == null && mThread != null) {
mThread.interrupt();
}
onCancelled();
mStatus = Status.FINISHED;
}
public AsyncTask<Param, Progress, Result> execute(final Param... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:" + " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:" + " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mParams = params;
if (mExecutor != null) {
mExecutor.execute(mRunnable);
} else {
mThread = new InternalThread();
mThread.start();
}
return this;
}
public Status getStatus() {
return mStatus;
}
public boolean isCancelled() {
return mCancelled;
}
protected abstract Result doInBackground(Param... params);
protected void onCancelled() {
}
protected void onCancelled(final Result result) {
}
protected void onPostExecute(final Result result) {
}
protected void onPreExecute() {
}
public enum Status {
RUNNING, PENDING, FINISHED
}
private final class BackgroundRunnable implements Runnable {
@Override
public void run() {
final Result result = doInBackground(mParams);
mHandler.post(new OnPostExecuteRunnable(result));
}
}
private final class InternalThread extends Thread {
@Override
public void run() {
mRunnable.run();
}
}
private final class OnPostExecuteRunnable implements Runnable {
final Result mResult;
public OnPostExecuteRunnable(final Result result) {
mResult = result;
}
@Override
public void run() {
if (isCancelled()) {
onCancelled(mResult);
} else {
onPostExecute(mResult);
}
mStatus = Status.FINISHED;
}
}
}