2012-02-03 27 views
33

Tengo un hilo que usa un controlador para publicar una instancia ejecutable. funciona bien, pero tengo curiosidad acerca de cómo pasaría los parámetros para usarlos en la instancia de Runnable. Quizás no entiendo cómo funciona esta característica.¿Hay alguna forma de pasar parámetros a Runnable?

Para adelantarse a una pregunta de "por qué necesita esto", tengo una animación enhebrada que tiene que volver a llamar al hilo de la interfaz de usuario para indicarle qué dibujar realmente.

Respuesta

67

Simplemente una clase que implementa Runnable con el constructor que acepta el parámetro puede hacer,

public class MyRunnable implements Runnable { 
    private Data data; 
    public MyRunnable(Data _data) { 
    this.data = _data; 
    } 

    @override 
    public void run() { 
    ... 
    } 
} 

Usted sólo puede crear una instancia de la clase Ejecutable con el constructor parametrizado.

MyRunnable obj = new MyRunnable(data); 
handler.post(obj); 
+2

Me gusta este enfoque, pero ¿cómo me comunico con esta clase desde dentro de mi hilo de temporizador (Runnable está fuera en el hilo principal de UI). ¿Puedo hacer que el miembro sea público y configurarlo en mi secuencia de tiempo antes de pasar Runnable al manejador? Parece demasiado bueno para ser verdad :) –

+0

Lamento contestar tarde, he editado mi respuesta. –

+0

Por alguna razón, pensé que si obj se crea en algún lugar que no sea el subproceso de interfaz de usuario, cuando intenta manipular una vista (en el hilo principal) la aplicación se bloqueará. Voy a darle un giro, muchas gracias. –

8

Hay varias maneras de hacerlo, pero lo más fácil es la siguiente:

final int param1 = value1; 
final int param2 = value2; 
... new Runnable() { 
    public void run() { 
     // use param1 and param2 here 
    } 
} 
+0

supongo que debería haber especificado que me gustaría evitar el uso de parametros globales en mi clase de esta manera ... :) Gracias, pero estoy tratando de obtener un método para pasar argumentos o usar algún otro constructo que los tome (si Runnable no lo hace) –

+0

Puedes almacenarlos como campos en Runnable pero eso es todo . También puede usar un Llamado. –

+0

Esto entrará en un problema de sincronización cuando se llame a la segunda publicación antes de que Runnable haya manejado la primera publicación. – marcelnijman

6

Si necesita comunicar información en un Runnable, siempre se puede tener el constructor Runnable objeto tomar esta información en, o podría tiene otros métodos en el Runnable que le permiten obtener esta información, o (si el Runnable es una clase interna anónima) podría declarar los valores apropiados final para que el Runnable pueda acceder a ellos.

Espero que esto ayude!

+0

Will Callable ¿está bien si se ejecuta desde un subproceso que no es el subproceso de interfaz de usuario? La razón por la que estoy haciendo esto para empezar es que no puedes llamar al hilo principal de Android si vas a alterar algún elemento de la interfaz de usuario. –

+0

@ Dr.Dredel- Sí, cualquier subproceso debería ser capaz de ejecutar un invocable. – templatetypedef

+0

+1 para usar una clase anónima que extienda 'Runnable' y haga referencia a variables' finales', siempre que solo se use en un punto –

1

Aunque se puede utilizar cualquiera de los anteriores la respuesta, pero si usted pregunta es realmente preocupados por el androide, entonces también puede utilizar AsyncTask.

+0

AsyncTask puede manipular vistas en el hilo de la interfaz de usuario (me doy cuenta de que esto solo es relevante en Android)? –

-1

creo una encontrado un método más sencillo:

public interface MyRunnable extends Runnable { 
    public void run(int data); 
} 

public void someMethod(int n, String s, MyRunnable r) { 
    ... 
    r.run(n); 
    ... 
} 

la llamada:

someMethod(5, "Hello", new MyRunnable() { 

    @Override 
    public void run(int data) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void run() { 
     // TODO Auto-generated method stub 

    } 
}); 
+0

Excepto que 'MyRunnable' no extiende' Runnable' por lo que no podrá usarlo cuando se espere un 'Runnable'. – assylias

+0

@assylias Una interfaz puede extender ejecutable si es necesario. – ilomambo

+0

Sí, pero ese no es el problema. Normalmente se llama 'new Thread (new MyRunnable() {...});', pero eso llamará al método 'run()', no al método 'run (int data);'. A menos que tenga el método 'run', llame al método' run (int data) ', pero ¿cómo pasa los parámetros? Intenta usar tu propuesta con un ejemplo real y verás los problemas. – assylias

Cuestiones relacionadas