android - usar - ¿Se puede llamar a NoticationManager.notify() desde un hilo de trabajo?
threads java wait notify (1)
Es aceptable actualizar una Notification
de un hilo de trabajo porque la Notification
no vive en el proceso de su aplicación y, por lo tanto, no está actualizando su UI directamente. La Notificación se mantiene en un proceso del sistema, y la IU de la Notification
se actualiza a través de RemoteViews
( doc ), que permite la manipulación de una jerarquía de vistas que es mantenida por un proceso que no es el suyo. Si miras la fuente de Notification.Builder
here , puedes ver que finalmente está construyendo un RemoteViews
.
Y si mira la fuente de RemoteViews
here , verá que cuando manipula una vista, en realidad solo crea un objeto Action
( source ) y lo agrega a una cola para ser procesado. Una Action
es un Parcelable
que finalmente se envía a través de IPC al proceso que posee la vista de Notification
, donde puede descomprimir los valores y actualizar la vista como se indica ... en su propio hilo de UI.
Espero que aclare por qué está bien actualizar una Notification
de un hilo de trabajo en su aplicación.
Mi pregunta es más acerca de qué es una buena práctica que lo que es posible:
- ¿Es bueno llamar a
NoticationManager.notify()
desde un hilo de trabajo? - ¿El sistema lo ejecuta en el hilo de UI de todos modos o no?
Siempre trato de recordar que todo lo relacionado con la interfaz de usuario debe ejecutarse en el hilo de la interfaz de usuario y el resto en subprocesos de trabajo, como sugiere el documento de Android sobre Procesos e hilos :
Además, el kit de herramientas de interfaz de usuario de Andoid no es seguro para subprocesos. Por lo tanto, no debe manipular su UI a partir de un hilo de trabajo: debe hacer toda la manipulación a su interfaz de usuario desde el hilo de UI. Por lo tanto, simplemente hay dos reglas para el modelo de un solo hilo de Android:
- No bloquee el hilo de UI
- No acceda al juego de herramientas de interfaz de usuario de Android desde fuera del hilo de la interfaz de usuario
SIN EMBARGO, me sorprendió un ejemplo dado por el documento de Android en sí ( acerca de mostrar el progreso en las notificaciones ), donde un progreso de notificación en curso se actualizó directamente desde un hilo de trabajo:
mNotifyManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_notification);
// Start a lengthy operation in a background thread
new Thread(
new Runnable() {
@Override
public void run() {
int incr;
// Do the "lengthy" operation 20 times
for (incr = 0; incr <= 100; incr+=5) {
// Sets the progress indicator to a max value, the
// current completion percentage, and "determinate"
// state
mBuilder.setProgress(100, incr, false);
// Displays the progress bar for the first time.
mNotifyManager.notify(0, mBuilder.build());
// Sleeps the thread, simulating an operation
// that takes time
try {
// Sleep for 5 seconds
Thread.sleep(5*1000);
} catch (InterruptedException e) {
Log.d(TAG, "sleep failure");
}
}
// When the loop is finished, updates the notification
mBuilder.setContentText("Download complete")
// Removes the progress bar
.setProgress(0,0,false);
mNotifyManager.notify(ID, mBuilder.build());
}
}
// Starts the thread by calling the run() method in its Runnable
).start();
Es por eso que me pregunto si realmente es necesario ejecutarlo en el hilo principal, o si el sistema se encarga de ello.
¡Gracias por tu ayuda!