2012-02-03 25 views
33

Ho una discussione che utilizza un gestore per pubblicare un'istanza eseguibile. funziona bene, ma sono curioso di sapere come passare i parametri da utilizzare nell'istanza Runnable? Forse non sto capendo come funziona questa funzionalità.C'è un modo per passare i parametri a un Runnable?

Per anticipare una domanda "perché ti serve", ho un'animazione filettata che deve richiamare il thread dell'interfaccia utente per dirgli cosa effettivamente disegnare.

risposta

67

semplicemente una classe che implementa Runnable con il costruttore che accetta il parametro può fare,

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

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

Si può solo creare un'istanza della classe Runnable con costruttore con parametri.

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

Mi piace questo approccio, ma come faccio a comunicare con questa classe dal mio thread del timer (il Runnable è nel thread dell'interfaccia utente principale). Posso rendere pubblico il membro e impostarlo nel mio thread del timer prima di passare il Runnable al gestore? Sembra troppo bello per essere vero :) –

+0

Mi dispiace rispondere in ritardo, ho modificato la mia risposta. –

+0

Per qualche ragione ho pensato che se obj è stato creato in un posto diverso dal thread dell'interfaccia utente, quindi quando tenta di manipolare una vista (nel thread principale) l'app si blocca. Gli darò un vortice, grazie molte. –

8

Ci sono vari modi per farlo, ma il più semplice è il seguente:

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

Credo che dovrei hanno precisato che vorrei evitare di usare params globali nella mia classe in questo modo ... :) Grazie, ma sto davvero cercando di ottenere un metodo per passare gli argomenti o utilizzare qualche altro costrutto che li prende (se Runnable no) –

+0

Puoi memorizzarli come campi nel Runnable ma questo è tutto . Puoi anche usare un Callable. –

+0

Si verificherà un problema di sincronizzazione quando viene chiamato il secondo post prima che il primo post sia gestito dal Runnable. – marcelnijman

6

Se avete bisogno di comunicare le informazioni in un Runnable, si può sempre avere il costruttore Runnable oggetto prendere queste informazioni in, o potrebbe avere altri metodi su Runnable che consentono di ottenere queste informazioni o (se la Runnable è una classe interna anonima) potrebbe dichiarare i valori appropriati final in modo che il Runnable possa accedervi.

Spero che questo aiuti!

+0

Callable può funzionare correttamente da un thread che non è il thread dell'interfaccia utente? La ragione per cui sto facendo questo per cominciare è che non puoi semplicemente chiamare il thread principale in Android se hai intenzione di modificare qualsiasi elemento dell'interfaccia utente. –

+0

@ Dr.Dredel- Sì, qualsiasi thread dovrebbe essere in grado di eseguire un Callable. – templatetypedef

+0

+1 per l'utilizzo di una classe anonima che estende le variabili 'Runnable' e referencing' final', purché sia ​​usato solo in un punto –

1

Sebbene sia possibile utilizzare una di queste la risposta, ma se si mette in discussione è davvero preoccupata per Android allora si può anche utilizzare AsyncTask.

+0

AsyncTask può manipolare Views nel thread dell'interfaccia utente (mi rendo conto che questo è rilevante solo in Android)? –

-1

Penso che un trovato un approccio più semplice:

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

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

la chiamata:

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

Tranne che 'MyRunnable' non estende' Runnable' quindi non sarà possibile utilizzarlo dove è previsto un 'Runnable'. – assylias

+0

@assylias Un'interfaccia può estendersi eseguibile se necessario. – ilomambo

+0

Sì ma non è questo il problema. Normalmente si chiama 'new Thread (new MyRunnable() {...});', ma questo chiamerà il metodo 'run()', non il metodo 'run (int data);'. A meno che tu non abbia il metodo 'run' chiama il metodo' run (int data) ', ma come passi i parametri allora? Prova ad usare la tua proposta con un esempio reale e vedrai i problemi. – assylias

Problemi correlati