2012-03-04 21 views
5

Il gestore di Android viene utilizzato per inviare messaggi tra classi. Per esempio:Esiste una classe in Java simile a android.os.Handler in Android?

public class Foo 
{ 

    private Handler handler; 

    public Foo(Handler handler) 
    { 
     this.handler = handler; 

     // ... 
    } 

    public void fooMethod() 
    { 
     // ... 
     handler.obtainMessage("blah blah").sendToTarget(); 
    } 

} 

principale:

public class Main 
{ 
    private Handler handler; 

    public Main() 
    { 
     handler = new Handler() 
     { 
      @Override 
      public void handleMessage(Message msg) 
      { 
       // handle the message that is sent from Foo 
      } 
     }; 

     Foo f = new Foo(handler); 

     // ... 
    } 
} 

Quindi, sto cercando una tecnica simile a Java, o dovrei realizzare il mio proprio gestore?

+3

'Handler' è progettato principalmente per consentire ai thread in background di organizzare il lavoro sul thread dell'applicazione principale (ad esempio, aggiornamenti dell'interfaccia utente). Oppure, per citare [la documentazione] (http://developer.android.com/reference/android/os/Handler.html), "Ci sono due usi principali per un gestore: (1) per pianificare i messaggi e i runnables da eseguito come un punto nel futuro e (2) per accodare un'azione da eseguire su un thread diverso rispetto al proprio. " Usare un "Gestore" per altri scopi è una pratica scorretta. – CommonsWare

+0

@CommonsWare Grazie per il consiglio. Voglio solo usare il meccanismo che è usato in Handler (io voglio reindirizzare un messaggio socket attraverso Internet tramite la classe 'Foo', e usarlo nella classe' Main'). –

+0

La maggior parte degli sviluppatori OO chiamerebbe semplicemente un metodo su "Main" da un'istanza di "Foo". – CommonsWare

risposta

2

non ce n'è uno per impostazione predefinita. Ma puoi creare una tua classe personalizzata che faccia una cosa simile. Ho fatto uno come questo:

import java.util.ArrayList; 

public class Handler extends Object{ 

ArrayList<Message> messages; 

public Handler(){ 
    messages = new ArrayList<>(); 
} 

public final Message obtainMessage(int what, Object obj){ 
    Message message = new Message(what, obj, this); 
    messages.add(message); 
    return message; 
} 

public final Message obtainMessage(int what){ 
    Message message = new Message(what, this); 
    messages.add(message); 
    return message; 
} 

public void handleMessage(Message msg){ 
    messages.remove(msg); 
} 

public final boolean hasMessages(){ 
    return !messages.isEmpty(); 
} 
} 

si sarebbe poi anche bisogno di una classe personalizzata messaggio come questo:

public class Message extends Object{ 

int mWhat; 
Object mObj; 
Handler mTarget; 

public Message(int what, Object obj){ 
    mWhat = what; 
    mObj = obj; 
} 

public Message(int what, Object obj, Handler target){ 
    mWhat = what; 
    mObj = obj; 
    mTarget = target; 
} 

public Message(int what, Handler target){ 
    mWhat = what; 
    mTarget = target; 
} 

public Message(int what){ 
    mWhat = what; 
} 

public void sendToTarget(){ 
    mTarget.handleMessage(this); 
} 
} 

È possibile utilizzare questo gestore per comunicare da un thread in background al thread UI, senza disturbare troppo il thread dell'interfaccia utente.

È possibile utilizzare questa classe in tutto allo stesso modo come si farebbe in Android: Per prima cosa è creare un'istanza nella classe UI:

final int MESSAGE_RECEIVED = 0; 
Handler handler = new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 
     super.handleMessage(msg); 
     switch (msg.mWhat){ 
      case MESSAGE_RECEIVED: 
       System.out.println("Message received."); 
       updateStatus("Message received."); 
       break; 
     } 
    } 
}; 

Poi si forniscono questa istanza Handler al tuo thread in background:

Thread thread = new T1(handler); 
thread.start(); 

E per ultimo, si inviano messaggi attraverso i mezzi di:

mHandler.obtainMessage(0).sendToTarget(); 

Ho testato questo metodo su un programma di applet di esempio che ho fatto, e sembra funzionare perfettamente. Anche se non sono un programmatore java esperto, quindi potrebbero esserci alcuni aspetti negativi di questo, di cui non sono realmente a conoscenza. Se è così, mi piacerebbe sentire una spiegazione colta del perché questo non è ok.

Spero che questo aiuti qualcuno.

NOTA: le precedenti classi Handler e Message (il mio codice) non forniscono tutte le funzionalità di Android.Handler e Android.Message.

+1

Questo non è in realtà il comportamento previsto. In Android handleMessage verrà eseguito sul thread se il gestore è stato creato (perché Handler è limitato al thread in cui è stato creato. Anche se l'utilizzo è simile, l'esempio che hai proposto verrà eseguito diverso dal gestore da Android Più esplicita, la parte di codice da handleMessage verrà eseguita sul thread (T1) non sul thread in cui è stato creato il gestore! –