Created
December 19, 2018 14:34
-
-
Save jesusbmx/5feaf9042e3e1625f683e430a00dd3aa to your computer and use it in GitHub Desktop.
Gestión de tareas en segundo plano para Android
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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