Don't mean to burst any bubbles here, but aren't we just recreating java.util.concurrent.Executors
, That is already android best practice to use for flexible concurrent tasks (i.e. thread & handler management)
From: android.os.AsyncTask
AsyncTask is designed to be a helper class around Thread and Handler
and does not constitute a generic threading framework. AsyncTasks
should ideally be used for short operations (a few seconds at the
most.) If you need to keep threads running for long periods of time,
it is highly recommended you use the various APIs provided by the
java.util.concurrent package such as Executor, ThreadPoolExecutor and
FutureTask.
From: java.util.concurrent.Executors
Factory and utility methods for Executor, ExecutorService,
ScheduledExecutorService, ThreadFactory, and Callable classes defined
in this package. This class supports the following kinds of methods:
- Methods that create and return an ExecutorService set up with commonly useful configuration settings.
- Methods that create and return a ScheduledExecutorService set up with commonly useful configuration settings.
- Methods that create and return a "wrapped" ExecutorService, that disables reconfiguration by making implementation-specific methods
inaccessible.
- Methods that create and return a ThreadFactory that sets newly created threads to a known state.
- Methods that create and return a Callable out of other closure-like forms, so they can be used in execution methods requiring Callable.
For Example (and what I believe Fildor was trying to get at):
//An Executor and a set of RunnableTasks to be executed
Executor executor = anExecutor();
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
The most simple means of direct execution in the caller's thread:
class DirectExecutor implements Executor {
public void execute(Runnable r) {
r.run();
}
}
This not an Asynchronous call, but can be easily executed as one, and not just the background thread, here is a version that spawns a new thread per task:
class ThreadPerTaskExecutor implements Executor {
public void execute(Runnable r) {
new Thread(r).start();
}
}
And you can impose any kind of limit such as serial execution:
class SerialExecutor implements Executor {
final Queue<Runnable> tasks = new ArrayDeque<>();
final Executor executor;
Runnable active;
SerialExecutor(Executor executor) {
this.executor = executor;
}
public synchronized void execute(final Runnable r) {
tasks.add(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (active == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((active = tasks.poll()) != null) {
executor.execute(active);
}
}
}
These are all text book examples, but it's easy to see that since it's already in there we don't need recreate the wheel, especially when it already supports the kind of wrapping that the MoinKahn is trying to achieve and is already best practice.
Thought I would add alink to Oracle's Executor Interface page, for more information on correct concurrency handling, and wrapping Executor Services.
Edit: Additionally here is a really good FutureTask example using ThreadPoolExecutor for in an in-depth answer from Gray on just that.