¿Las devoluciones de llamada se producen en el hilo principal (UI)?

Hay muchas APIs de SDK de Android en las que se registran los controladores de devolución de llamada. Para un ejemplo concreto, con MediaPlayer puede establecer una devolución de llamada onCompletionListener. ¿Se llamarán estas devoluciones de llamada desde el hilo principal (UI)? Si la respuesta es "depende", entonces estoy buscando algunas reglas generales para lo que las devoluciones de llamada se llamará desde el hilo principal frente a otro hilo. La documentación del SDK no parece explicarlo. (Tal vez lo extrañé.)

Parece importante saber, porque si estoy garantizado retornos de llamada principales, entonces puedo saltar una sincronización de hilos en los datos compartidos entre diferentes lugares en el código. Si me veo forzado a ser pesimista por ignorancia, entonces tengo que escribir código de bloques de sincronización extra y preocuparme por los deadlocks, la integridad de los datos y el rendimiento reducido.

Un caso en el que Android llamará a su código en algún otro hilo será si crea un servicio remoto, expuesto a través de AIDL – los métodos AIDL se llamará en un hilo de enlace, no el hilo de la aplicación principal.

Sin embargo, esa es la excepción. Como los otros han señalado, la gran mayoría de estos se llaman en el hilo principal de la aplicación.

En caso de duda, puede utilizar Log.i("TAG", Thread.currentThread().getName()); y ver 🙂

En mi experiencia, esas devoluciones siempre vuelven en un hilo no UI. ¿Ha intentado Activity.runOnUiThread() para asegurarse de que su código se ejecuta en el subproceso de interfaz de usuario? Seguiría teniendo el éxito de rendimiento porque tarda más tiempo en ejecutar este código, pero evitaría algunos de los problemas más comunes con la sincronización de subprocesos.

En general, las devoluciones de llamada se producirán en el subproceso en el que se ejecuta el evento. Si registra una devolución de llamada e inicia algo que se reproduce en un subproceso no UI, la devolución de llamada se producirá en el subproceso no UI. Sin embargo, Android no va a crear nuevos temas en el fondo por su cuenta.

Todos los eventos relacionados con la interfaz de usuario deben producirse en el subproceso de la interfaz de usuario, por lo que puede calcular que las devoluciones de llamada del controlador de clics, etc. se producirán en el subproceso de la interfaz de usuario.

Como señaló Aaron C, puede usar Activity.runOnUiThread para forzar que las cosas ocurran allí.

Además, el AsyncTask puede ser muy útil para hacer un trabajo de fondo rápido, donde necesita algún paso de finalización para estar garantizado para estar en el subproceso de uI.

Editar: Ejemplo de los comentarios.

 public void MyWorker { private OnCompleteListener onCompleteListener; public void setOnCompleteListener(OnCompleteListener onCompleteListener) { this.onCompleteListener = onCompleteListener; } public void doWork() { // do lots of work here onCompleteListener.onComplete(); } } // somewhere in my Activity public void onCreate() { final MyWorker worker = new MyWorker(); worker.setOnCompleteListener(new OnCompleteListener() { ... }); new Thread(new Runnable() { public void run() { worker.doWork(); } }).start(); } 

En este ejemplo, la "devolución de llamada" onComplete se ejecutará desde el subproceso no UI. El subproceso saldrá después de terminar onComplete.

Otra excepción es la opción Cuando está utilizando WebView. Cuando javascript llama a una función Java, tal invocación no sucederá en el hilo principal

Algo similar surgió cuando trabajaba en API de ubicación. Como sabemos, proporcionamos una devolución de llamada para los servicios de Ubicación, para que nos notifiquemos una vez que hayamos adquirido una ubicación. Así que estaba haciendo algo en esta devolución de llamada que estaban tardando mucho tiempo como usar API de Geocoder.

Yo estaba bajo impresión antes de que, esta devolución de llamada se llama desde otro hilo y por lo tanto no se ejecuta en el hilo principal de interfaz de usuario. Pero puedo ver, no es el caso.

Así que cualquier código que escriba en este listener será ejecutado en el hilo principal.

Ahora lo que no entiendo es cómo se las arreglan para hacer eso, es mediante el uso de una función runOnUIThread() ???

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.