2011-10-22 6 views
20

Nella mia applicazione, in MainActivity, c'è una discussione che funziona bene. Ma quando chiamo un'altra classe per ottenere dati dal server, non posso correre su un thread. Vedere l'esempio di codice qui sotto.Android come eseguireOnUiThread in un'altra classe?

class MainActivity extends Activity implements Runnable { 

    public void onCreate() { 
     new Thread(this).start(); 
    } 

    public void run() { 
     //here is code for download data from server after completion this and in handler i m call other class in setdata() method.... 
    } 

    public void setData() { 
     new CheckData(this); 
    } 
} 

class CheckData { 
    public CheckData(Context context) { 
     context.runUIonthread(){//cant call as runUIthread............ 
    } 
} 

risposta

39

vedere l'articolo Communicating with the UI Thread.

Con Context in mano, è possibile creare un Handler in qualsiasi classe. Altrimenti, è possibile chiamare Looper.getMainLooper(), in entrambi i casi, si ottiene il thread dell'interfaccia utente principale.

Ad esempio:

class CheckData{ 
    private final Handler handler; 

    public Checkdata(Context context){ 
     handler = new Handler(context.getMainLooper()); 
    } 

    public void someMethod() { 
     // Do work 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       // Code to run on UI thread 
      } 
     }); 
    } 

    private void runOnUiThread(Runnable r) { 
     handler.post(r); 
    } 
} 
+0

in che modo il gestore può essere definitivo senza essere inizializzato?: ^) – Sipty

+0

I campi finali di @Styty possono essere inizializzati nel costruttore, come nel mio esempio. Il costruttore –

+2

non ha valore di ritorno. E i nomi delle classi Java dovrebbero iniziare con la lettera maiuscola BTW. Nonostante abbia piccoli errori, la tua risposta è utile! – hgoebl

6

Si potrebbe dare un'occhiata a AsyncTask. Anche se non è la soluzione migliore, ti aiuterà a iniziare.

http://developer.android.com/reference/android/os/AsyncTask.html

EDIT

non vedo il motivo per cui utilizzando un AsyncTask non è una soluzione per voi, ma in ogni caso. Puoi tenere una classe Handler inizializzata nel thread dell'interfaccia utente. Quindi usando questo Handler puoi postare i messaggi nell'interfaccia utente sotto forma di eseguibile. Quindi tutto ciò che devi fare è creare un'istanza di un nuovo oggetto Handler quando sei nel thread dell'interfaccia utente (prima di avviarne uno nuovo) e condividerlo con l'altra classe. Quando hai finito, puoi usare quell'istanza per postare un messaggio sul thread dell'interfaccia utente usando il metodo post. Controlla la documentazione della classe Handler per maggiori dettagli:

http://developer.android.com/reference/android/os/Handler.html

+0

no, non una soluzione per questo compito uso asincrona? io uso solo il thread .. niente altro ....... –

+0

AsyncTask avvolge il thread separato e tutte le sue manipolazioni e implementazioni nella sua classe, rendendo molto più facile l'utilizzo. È un'ottima soluzione per ciò di cui hai bisogno (download di dati da un server). Implementa solo alcuni metodi di callback, ad esempio quando viene eseguita l'attività, prima che sia avviata e così via ... E quindi lo si avvia dal metodo onCreate. – Jong

+0

@Jong lo so molto bene ma ho bisogno di una soluzione perché non possiamo chiamare runUIthread? quindi leggi attentamente la domanda ........ –

11
class MainActivity extends Activity implements Runnable{ 

    public void oncreate(){ 
     new Thread(this).start(); 
    } 

    public void run(){ 
     //here is code for download data from server after completion this and in handler i m call other class in setdata() method.... 
    } 

    public void setdata(); 
    { 
     new checkData(this,MainActivity.this); 
    } 
} 

class checkData{ 

    public void checkdata(Context context,MainActivity mainactivity){ 
     mainactivity.runUIonthread()..is works fine for me..... 
    } 

} 
+0

Hai visto il tuo post sul blog su twitter. Avere un dubbio Puoi chiarire per favore? – Apparatus

+0

È ridondante passare l'attività quando si passa il contesto. Si prega di guardare la soluzione che ho condiviso qui sotto http://stackoverflow.com/a/28873148/2670370. –

10

attività è una classe che estende Context. Quindi non è necessario passare sia il contesto che l'attività. Si può passare attività di contesto e quindi è possibile utilizzare il contesto per l'esecuzione su thread UI come segue:

((Activity) context).runOnUiThread(new Runnable() { 
     public void run() { 
      //Code goes here 
     } 
    }); 

parola di cautela: utilizzare solo quando sei sicuro che il contesto è un contesto di attività, e non è una buona pratica pensarlo.

+0

Se si sta già passando il contesto, questa è la soluzione di lavoro più semplice. –

21

Ecco una soluzione se non si vuole passare il contesto:

new Handler(Looper.getMainLooper()).post(new Runnable() { 
    public void run() { 
     // code goes here 
    } 
}); 
+0

Ha funzionato per me, grazie –

+0

è una soluzione semplice ed efficace per questo caso. grazie. – Al2x

0

Se qualcuno è alla ricerca di una soluzione basata su Rx:

Observable.just(true) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(aBoolean -> { 
     // cool stuff comes here 
    }); 
Problemi correlati