uso thread termine tareas subprocesos studio que hilos esperar ejemplo asynctask asincronos asincronas android multithreading android-handler

android - thread - Ejecutando código en el hilo principal de otro hilo



thread android studio ejemplo (12)

Como un comentarista a continuación señaló correctamente, esta no es una solución general para servicios, solo para subprocesos iniciados desde su actividad (un servicio puede ser un subproceso de este tipo, pero no todos lo son). En el complicado tema de la comunicación de servicio-actividad, lea toda la sección de Servicios del documento oficial: es complejo, por lo que le convendría comprender los conceptos básicos: http://developer.android.com/guide/components/services.html#Notifications

El método a continuación puede funcionar en los casos más simples.

Si le comprendo correctamente, necesita que se ejecute algún código en el subproceso de la GUI de la aplicación (no se puede pensar en nada más que se llame subproceso "principal"). Para esto hay un método de Activity :

someActivity.runOnUiThread(new Runnable() { @Override public void run() { //Your code to run in GUI thread here }//public void run() { });

Doc: http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29

Espero que esto sea lo que buscas.

En un servicio de Android, he creado subprocesos para realizar alguna tarea en segundo plano.

Tengo una situación en la que un subproceso necesita publicar cierta tarea en la cola de mensajes del subproceso principal, por ejemplo, un Runnable .

¿Hay alguna manera de obtener un Handler del hilo principal y publicar un Message / Runnable en mi otro hilo?

Gracias,


Hay otra forma sencilla, si no tiene acceso al Contexto.

1). Crea un manejador desde el looper principal:

Handler uiHandler = new Handler(Looper.getMainLooper());

2). Implementar una interfaz Runnable:

Runnable runnable = new Runnable() { // your code here }

3). Publique su Runnable en el uiHandler:

uiHandler.post(runnable);

Eso es todo ;-) Diviértete con hilos, pero no olvides sincronizarlos.


La forma más sencilla, especialmente si no tiene un contexto, si está utilizando RxAndroid, puede hacerlo:

AndroidSchedulers.mainThread().scheduleDirect { runCodeHere() }


NOTA: Esta respuesta ha recibido tanta atención que necesito actualizarla. Desde que se publicó la respuesta original, el comentario de @dzeikei ha recibido casi tanta atención como la respuesta original. Así que aquí hay 2 soluciones posibles:

1. Si su hilo de fondo tiene una referencia a un objeto de Context :

Asegúrese de que sus subprocesos de trabajo en segundo plano tengan acceso a un objeto de contexto (puede ser el contexto de la aplicación o el contexto del servicio). Entonces haz esto en el hilo del trabajador de fondo:

// Get a handler that can be used to post to the main thread Handler mainHandler = new Handler(context.getMainLooper()); Runnable myRunnable = new Runnable() { @Override public void run() {....} // This is your code }; mainHandler.post(myRunnable);

2. Si su hilo de fondo no tiene (o necesita) un objeto de Context

(sugerido por @dzeikei):

// Get a handler that can be used to post to the main thread Handler mainHandler = new Handler(Looper.getMainLooper()); Runnable myRunnable = new Runnable() { @Override public void run() {....} // This is your code }; mainHandler.post(myRunnable);


Para Kotlin, puedes usar Anko Corountines :

actualizar

doAsync { ... }

obsoleto

async(UI) { // Code run on UI thread // Use ref() instead of this@MyActivity }


Sé que esta es una pregunta antigua, pero encontré un hilo principal de una línea que uso tanto en Kotlin como en Java. Puede que esta no sea la mejor solución para un servicio, pero para llamar a algo que cambiará la interfaz de usuario dentro de un fragmento, esto es extremadamente simple y obvio.

Java (8):

getActivity().runOnUiThread(()->{ //your main thread code });

Kotlin:

this.runOnUiThread(()->{ //your main thread code });


Si ejecuta código en un hilo, por ejemplo, retrasando alguna acción, entonces necesita invocar runOnUiThread desde el contexto. Por ejemplo, si su código está dentro de la clase MainActivity , use esto:

MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { myAction(); } });

Si su método puede invocarse desde el subproceso principal (UI) o desde otros subprocesos, necesita una comprobación como:

public void myMethod() { if( Looper.myLooper() == Looper.getMainLooper() ) { myAction(); } else { }


Sigue este método. Usando de esta manera, simplemente puede actualizar la interfaz de usuario desde un hilo de fondo. RunOnUiThread funciona en el hilo principal (UI). Creo que este fragmento de código es menos complejo y fácil, especialmente para los principiantes.

AsyncTask.execute(new Runnable() { @Override public void run() { //code you want to run on the background someCode(); //the code you want to run on main thread MainActivity.this.runOnUiThread(new Runnable() { public void run() { /*the code you want to run after the background operation otherwise they will executed earlier and give you an error*/ executeAfterOperation(); } }); } });

en el caso de un servicio

crear un manejador en el oncreate

handler = new Handler();

entonces úsalo así

private void runOnUiThread(Runnable runnable) { handler.post(runnable); }


Un bloque de código condensado es el siguiente:

new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { // things to do on the main thread } });

Esto no implica pasar la referencia de actividad o la referencia de aplicación.

Equivalente Kotlin:

Handler(Looper.getMainLooper()).post(Runnable { // things to do on the main thread })


Un método que puedo pensar es el siguiente:

1) Deje que la UI se una al servicio.
2) Exponga un método como el que se encuentra abajo en el Binder que registra su Handler :

public void registerHandler(Handler handler) { mHandler = handler; }

3) En el subproceso de la interfaz de usuario, llame al método anterior después de vincular al servicio:

mBinder.registerHandler(new Handler());

4) Utilice el controlador en el hilo del Servicio para publicar su tarea:

mHandler.post(runnable);


HandlerThread es una mejor opción para los HandlerThread normales de Java en Android.

  1. Crear un HandlerThread e iniciarlo
  2. Cree un controlador con Looper desde HandlerThread: requestHandler
  3. post una tarea requestHandler en requestHandler

Comunicación con el hilo de UI de HandlerThread

  1. Cree un Handler con Looper para el hilo principal: responseHandler y anule el método handleMessage
  2. Dentro de la tarea Runnable de otro hilo ( HandlerThread en este caso), llame a sendMessage en responseHandler
  3. Esta invocación del resultado de handleMessage de handleMessage en responseHandler .
  4. Obtenga los atributos del Message y procéselo, actualice la interfaz de usuario

Ejemplo : actualice TextView con los datos recibidos de un servicio web. Dado que el servicio web debe invocarse en un hilo no UI, se creó HandlerThread para la operación de red. Una vez que obtenga el contenido del servicio web, envíe un mensaje a su controlador de subproceso principal (Hilo de la interfaz de usuario) y ese Handler manejará el mensaje y actualizará la interfaz de usuario.

Código de muestra:

HandlerThread handlerThread = new HandlerThread("NetworkOperation"); handlerThread.start(); Handler requestHandler = new Handler(handlerThread.getLooper()); final Handler responseHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { txtView.setText((String) msg.obj); } }; Runnable myRunnable = new Runnable() { @Override public void run() { try { Log.d("Runnable", "Before IO call"); URL page = new URL("http://www.your_web_site.com/fetchData.jsp"); StringBuffer text = new StringBuffer(); HttpURLConnection conn = (HttpURLConnection) page.openConnection(); conn.connect(); InputStreamReader in = new InputStreamReader((InputStream) conn.getContent()); BufferedReader buff = new BufferedReader(in); String line; while ((line = buff.readLine()) != null) { text.append(line + "/n"); } Log.d("Runnable", "After IO call:"+ text.toString()); Message msg = new Message(); msg.obj = text.toString(); responseHandler.sendMessage(msg); } catch (Exception err) { err.printStackTrace(); } } }; requestHandler.post(myRunnable);

Artículos útiles:

handlerthreads-and-why-you-should-be-using-them-in-your-android-apps

android-looper-handler-handlerthread-i


public void mainWork() { new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { //Add Your Code Here } }); }

Esto también puede funcionar en una clase de servicio sin problemas.