getlooper - handler thread android
HandlerThread vs Executor-¿Cuándo es uno más apropiado que el otro? (2)
La clase Executor es más poderosa y puede usar un grupo de subprocesos, mientras que cada controlador hace referencia a un solo subproceso. El ejecutor le permite obtener todas las tareas programadas y cancelarlas si lo desea. El Manejador, por otro lado, no responderá preguntas simples como, cuántas tareas están esperando o me dará una referencia a todas las tareas en espera. Creo que una de las razones por las que Handler es más limitado es porque Android te da acceso al Handler principal que usa para la interfaz de usuario y puedes arruinar realmente el sistema operativo si comienzas a cancelar las tareas del sistema operativo.
En general, si necesita un grupo de hilos o mucha potencia, use el Ejecutor. Si solo necesita un buen hilo de fondo para ejecutar una tarea a la vez, use un Manejador. Como ejemplo, cuando quiero consultar mi base de datos, solo quiero que ocurra una consulta a la vez y no quiero generar un ANR, así que utilizo un controlador que se ejecuta en un hilo de fondo para ejecutar mis consultas.
Creo que su elección de ejecutor parece apropiada, ya que quiere manejar múltiples solicitudes entrantes simultáneamente y un Manejador solo puede hacerlo de a una por vez.
ACTUALIZACIÓN: Cómo crear un controlador que se ejecuta en un hilo de fondo:
En su constructor o onCreate, escriba lo siguiente, obviamente puede establecer la prioridad a su gusto:
public class MyClass {
private Handler mBgHandler;
public MyClass() {
HandlerThread bgThread = new HandlerThread("My-Background-Handler");
bgThread.start();
mBgHandler = new Handler(bgThread.getLooper());
}
}
ACTUALIZACIÓN: no se olvide de salir () o salir de Safe () su HandlerThread cuando haya terminado con él, de lo contrario, seguirá esperando por siempre
Solo tengo curiosidad sobre si hay momentos en los que debería elegir un Executor
sobre un HandlerThread
. ¿Hay momentos en que uno es superior al otro, o debería simplemente seguir con HandlerThread
? En mi caso, actualmente estoy escuchando un ServerSocket
para las conexiones, y manejo cada solicitud en un hilo separado creado por un Executor
. Aunque di un ejemplo específico, realmente estoy buscando casos en los que uno es más apropiado que el otro. Sin embargo, doy la bienvenida a los comentarios sobre mi diseño.
No seguiría el código de muestra en la respuesta de satur9nine a partir de 2011-Dic-22.
Thread.MIN_PRIOROTY está asignado a android.os.Process.THREAD_PRIORITY_LOWEST. Quote :
Prioridad de hilo más baja disponible. Solo para aquellos que realmente no quieren correr si algo más está sucediendo.
Al menos usaría android.os.Process.THREAD_PRIORITY_BACKGROUND, así:
HandlerThread bgThread = new HandlerThread("handler name");
Process.setThreadPriority(bgThread.getThreadId(), Process.THREAD_PRIORITY_BACKGROUND);
bgThread.start();
mBgHandler = new Handler(bgThread.getLooper());
Esto asigna la prioridad predeterminada de fondo de Android al hilo.
Actualmente, los subprocesos de prioridad Process.THREAD_PRIORITY_BACKGROUND y de abajo comparten una cantidad artificialmente limitada de tiempo de CPU por medio de un cgroup de Linux, ver por ejemplo here . Si una tarea en segundo plano no solo espera la E / S sino que realiza cálculos reales, consideraría aumentar su prioridad mediante android.os.Process.THREAD_PRIORITY_MORE_FAVORABLE que (actualmente) lo mueve fuera del grupo cgroup de fondo sin poner en peligro sustancialmente la IU y actividades en tiempo real.
Actualización: la respuesta de satur9nine se revisó silenciosamente en 2013-ene-08 para no establecer la prioridad más baja posible. El HandlerThread ahora tendrá implícitamente una prioridad de android.os.Process.THREAD_PRIORITY_BACKGROUND. Esto significa que ahora obtiene la prioridad predeterminada de la tarea en segundo plano, pero aún está limitada a consumir un máximo artificial de 10% de tiempo de CPU junto con todas las demás tareas en segundo plano que puedan existir. Si eso no es deseado, use mi código anterior, por ejemplo, con
Process.setThreadPriority(bgThread.getThreadId(),
Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
para levantar su hilo de fondo fuera del cgroup.