En el punto de vista del código en ejecución en el hilo de la interfaz de usuario, ¿hay alguna diferencia entre:
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Log.d("UI thread", "I am the UI thread");
}
});
o
MainActivity.this.myView.post(new Runnable() {
public void run() {
Log.d("UI thread", "I am the UI thread");
}
});
y
private class BackgroundTask extends AsyncTask<String, Void, Bitmap> {
protected void onPostExecute(Bitmap result) {
Log.d("UI thread", "I am the UI thread");
}
}

Respuestas:
Ninguno de ellos es exactamente el mismo, aunque todos tendrán el mismo efecto neto.
La diferencia entre el primero y el segundo es que si se encuentra en el hilo principal de la aplicación al ejecutar el código, el primero (
runOnUiThread()) ejecutará elRunnableinmediatamente. El segundo (post()) siempre coloca elRunnableal final de la cola de eventos, incluso si ya está en el hilo principal de la aplicación.El tercero, suponiendo que cree y ejecute una instancia de
BackgroundTask, perderá mucho tiempo sacando un subproceso del grupo de subprocesos, para ejecutar un no operativo predeterminadodoInBackground(), antes de hacer lo que equivale a apost(). Este es, con mucho, el menos eficiente de los tres. ÚseloAsyncTasksi realmente tiene trabajo que hacer en un hilo de fondo, no solo para el uso deonPostExecute().fuente
AsyncTask.execute()requiere que llame desde el hilo de la interfaz de usuario de todos modos, lo que hace que esta opción sea inútil para el caso de usar simplemente ejecutar código en el hilo de la interfaz de usuario desde un hilo de fondo a menos que mueva todo su trabajo de fondodoInBackground()y lo useAsyncTaskcorrectamente.AsyncTaskdesde el hilo de la interfaz de usuario?boolean isUiThread = (Looper.getMainLooper().getThread() == Thread.currentThread());Looper.getMainLooper().isCurrentThreadMe gusta el comentario de HPP , se puede usar en cualquier lugar sin ningún parámetro:
fuente
Hay una cuarta forma de usar
Handlerfuente
new Handler(Looper.getMainLooper()).post(r), que es la forma preferida deLooper.getMainLooper()hacer una llamada estática a main, mientras quepostOnUiThread()debe tener una instancia deMainActivityalcance.La respuesta de Pomber es aceptable, sin embargo, no soy un gran admirador de crear nuevos objetos repetidamente. Las mejores soluciones son siempre las que intentan mitigar el consumo de memoria. Sí, hay recolección automática de basura, pero la conservación de la memoria en un dispositivo móvil cae dentro de los límites de las mejores prácticas. El siguiente código actualiza TextView en un servicio.
Se puede usar desde cualquier lugar como este:
fuente
The best solutions are always the ones that try to mitigate memory hog. Hay muchos otros criterios parabest, y esto tiene un ligero olor apremature optimization. Es decir, a menos que sepa que lo está llamando lo suficiente como para que el número de objetos creados sea un problema (en comparación con las otras diez mil formas en que su aplicación probablemente está creando basura), lo que puede serbestes escribir el más simple (más fácil de entender ), y pasar a otra tarea.textViewUpdaterHandlersería mejor nombrar algo comouiHandleromainHandler, ya que generalmente es útil para cualquier publicación en el hilo principal de la interfaz de usuario; no está en absoluto vinculado a su clase TextViewUpdater. Lo alejaría del resto de ese código y dejaría en claro que se puede usar en otro lugar ... El resto del código es dudoso, porque para evitar crear un objeto dinámicamente, divide lo que podría ser una sola llamada dos pasossetTextypostque dependen de un objeto de larga duración que se usa como temporal. Complejidad innecesaria y no segura para subprocesos. No es fácil de mantener.uiHandlerytextViewUpdater, a continuación, mejorar su clase cambiando apublic void setText(String txt, Handler uiHandler)y añadiendo la línea métodouiHandler.post(this);Luego la persona que llama puede hacer en un solo paso:textViewUpdater.setText("Hello", uiHandler);. Luego, en el futuro, si necesita ser seguro para subprocesos, el método puede envolver sus declaraciones dentro de un bloqueouiHandlery la persona que llama permanece sin cambios.A partir de Android P puedes usar
getMainExecutor():De los documentos para desarrolladores de Android :
Del CommonsBlog :
fuente
Si necesita usar Fragment, debe usar
en vez de
Porque habrá una excepción de puntero nulo en alguna situación como fragmento de buscapersonas
fuente
Hola chicos, esta es una pregunta básica.
utilizar Handler
fuente
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()si no se llama desde el hilo de la interfaz de usuario.