Skip to content

Instantly share code, notes, and snippets.

@jesusbmx
Created December 19, 2018 14:34
Show Gist options
  • Save jesusbmx/5feaf9042e3e1625f683e430a00dd3aa to your computer and use it in GitHub Desktop.
Save jesusbmx/5feaf9042e3e1625f683e430a00dd3aa to your computer and use it in GitHub Desktop.
Gestión de tareas en segundo plano para Android
import android.os.Handler;
import android.os.Looper;
import android.os.Process;
import android.util.Log;
import java.util.concurrent.LinkedBlockingQueue;
/** Clase que procesa tareas en segundo plano. */
public class TaskPool extends Thread {
private static final String TAG = TaskPool.class.getSimpleName();
private static final TaskPool INSTANCE = new TaskPool();
/** Cola de peticiones. */
private final LinkedBlockingQueue<Request<?>> mQueue;
/** Es usado para decir que el hilo a muerto. */
private volatile boolean mQuit = false;
/** Puente que comunica las tareas con el hilo principal de la UI. */
private final Handler mHandler;
public interface Call<T> {
void execute(Callback<T> callback);
}
public interface Callback<T> {
void onResponse(T result);
void onError(Exception e);
}
public interface Task<T> {
T doInBackground() throws Exception;
}
public static class Request<T> {
final Callback<T> callback;
final Task<T> task;
Request(Callback<T> callback, Task<T> task) {
this.callback = callback;
this.task = task;
}
}
private TaskPool() {
mHandler = new Handler(Looper.myLooper());
mQueue = new LinkedBlockingQueue<Request<?>>();
}
public static TaskPool get() {
return INSTANCE;
}
/** Obliga al hilo a detenerce inmediatamente. */
@Override public void interrupt() {
mQuit = true;
super.interrupt();
}
/** Crea un escuchador. */
public static <V> Call<V> newCall(final Task<V> task) {
return new Call<V>() {
@Override public void execute(Callback<V> callback) {
TaskPool pool = TaskPool.get();
pool.execute(new Request<V>(callback, task));
}
};
}
/** Agrega la tarea a la cola de peticiones. */
private void execute(Request<?> request) {
if (getState() == State.NEW) {
Log.w(TAG, "El hilo se ha iniciado");
start();
}
mQueue.add(request);
}
/**
* Metodo que desarrolla un bucle que estara observando si existe una o varias
* 'Tareas' en la cola, si hay una tarea la procesara.
*/
@Override public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
while (true) {
Request<?> request;
try {
// Toma y quita la peticion de la cola.
request = mQueue.take();
} catch (InterruptedException e) {
// El hilo pudo haber sido interrumpido.
if (mQuit) return;
continue;
}
try {
Object result = request.task.doInBackground();
deliveryResponse(request.callback, result);
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
deliveryErrorResponse(request.callback, e);
}
}
}
/** Metodo que se encarga de liverar la respuesta obtenida de la conexión. */
private void deliveryResponse(final Callback callback, final Object result) {
mHandler.post(new Runnable() {
@Override public void run() {
callback.onResponse(result);
}
});
}
/** Metodo que se encarga de liverar el error obtenido de la conexión. */
private void deliveryErrorResponse(final Callback callback, final Exception result) {
mHandler.post(new Runnable() {
@Override public void run() {
callback.onError(result);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment