it-swarm.com.de

Zugriff auf den UI-Thread-Handler von einem Dienst aus

Ich versuche etwas Neues auf Android, für das ich auf den Handler des UI-Threads zugreifen muss.

Ich weiß folgendes:

  1. Der UI-Thread hat einen eigenen Handler Und einen Looper 
  2. Jede Nachricht wird in die Nachrichtenwarteschlange des UI-Threads eingefügt 
  3. Der Looper nimmt das Ereignis Auf und leitet es an den Handler weiter 
  4. Der Handler verarbeitet die Nachricht und Sendet das spezifische Ereignis an die Benutzeroberfläche

Ich möchte meinen Dienst haben, der den UI-Thread-Handler abrufen und eine Nachricht in diesen Handler einfügen muss, damit diese Nachricht verarbeitet und an die Benutzeroberfläche ausgegeben wird. Hier wird der Dienst normal sein Dienst, der von einer Anwendung gestartet wird.

Ich würde gerne wissen, ob dies möglich ist ... Wenn ja, schlagen Sie bitte einige Code-Schnipsel vor, damit ich es ausprobieren kann.

Grüße Girish

85
iLikeAndroid

Dieses Codefragment erstellt einen Handler, der mit dem Haupt-UI-Thread verknüpft ist:

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

Sie können dann im Hauptthread (UI-Thread) Sachen wie folgt zur Ausführung buchen:

handler.post(runnable_to_call_from_main_thread);

Wenn der Handler selbst aus dem Haupt-UI-Thread erstellt wird, kann das Argument der Kürze halber weggelassen werden:

Handler handler = new Handler();

Der Android Dev Guide zu Prozessen und Threads enthält weitere Informationen.

170
volley

Erstellen Sie ein Messenger-Objekt, das Ihrer Handler angehängt ist, und übergeben Sie diese Messenger an die Service (z. B. in einem Intent-Zusatz für startService()). Die Service kann dann über die Message eine Handler an die Messenger senden. Hier ist eine Beispielanwendung , die dies demonstriert.

28
CommonsWare

Im Moment ziehe ich es vor, die Event Bus Library wie Otto für dieses Problem zu verwenden. Abonnieren Sie einfach die gewünschten Komponenten (Aktivität):

protected void onResume() {
    super.onResume();
    bus.register(this);
}

Geben Sie dann eine Rückrufmethode an:

public void onTimeLeftEvent(TimeLeftEvent ev) {
    // process event..
}

und dann, wenn Ihr Dienst eine Anweisung wie folgt ausführt:

bus.post(new TimeLeftEvent(340));

Dieses POJO wird an Ihre obige Aktivität und alle anderen abonnierenden Komponenten übergeben. Einfach und elegant.

4
pram

Sie können Werte über den Broadcast-Empfänger erhalten. So erstellen Sie zunächst Ihren eigenen IntentFilter als

Intent intentFilter=new IntentFilter();
intentFilter.addAction("YOUR_INTENT_FILTER");

Dann erstellen Sie die innere Klasse BroadcastReceiver als

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    /** Receives the broadcast that has been fired */
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction()=="YOUR_INTENT_FILTER"){
           //HERE YOU WILL GET VALUES FROM BROADCAST THROUGH INTENT EDIT YOUR TEXTVIEW///////////
           String receivedValue=intent.getStringExtra("KEY");
        }
    }
};

Registrieren Sie jetzt Ihren Broadcast-Empfänger in onResume () als,

registerReceiver(broadcastReceiver, intentFilter);

Und schließlich die Registrierung von BroadcastReceiver in onDestroy () aufheben als,

unregisterReceiver(broadcastReceiver);

Nun das Wichtigste ... Sie müssen die Sendung von überall aus feuern, wo Sie Werte senden müssen.

Intent i=new Intent();
i.setAction("YOUR_INTENT_FILTER");
i.putExtra("KEY", "YOUR_VALUE");
sendBroadcast(i);

....Prost :)

2
Melbourne Lopes

Ich schlage vor, folgenden Code zu versuchen:

    new Handler(Looper.getMainLooper()).post(() -> {

        //UI THREAD CODE HERE



    });
0
user2983041

In kotlin können Sie dies tun

Sagen Sie, ob Sie die Toast-Nachricht vom Dienst anzeigen möchten

val handler = Handler(Looper.getMainLooper())
handler.post {
   Toast.makeText(context, "This is my message",Toast.LENGTH_LONG).show()
}
0
Zohab Ali

Lösung:

  1. Erstellen Sie einen Handler mit Looper vom Haupt-Thread: requestHandler
  2. Erstellen Sie eine Handler mit Looper aus dem Main Thread: responseHandler und überschreiben Sie die handleMessage-Methode
  3. stellen Sie eine Runnable - Aufgabe auf requestHandler
  4. Rufen Sie in der Task Runnable sendMessage für responseHandler auf
  5. Dies sendMessage führt zum Aufruf von handleMessage in responseHandler.
  6. Holen Sie sich Attribute aus der Variablen Message und verarbeiten Sie sie, aktualisieren Sie die Benutzeroberfläche

Beispielcode:

    /* Handler from UI Thread to send request */

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

     /* Handler from UI Thread to process messages */

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {

            /* Processing handleMessage */

            Toast.makeText(MainActivity.this,
                    "Runnable completed with result:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

    for ( int i=0; i<10; i++) {
        Runnable myRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                   /* Send an Event to UI Thread through message. 
                      Add business logic and prepare message by 
                      replacing example code */

                    String text = "" + (++rId);
                    Message msg = new Message();

                    msg.obj = text.toString();
                    responseHandler.sendMessage(msg);
                    System.out.println(text.toString());

                } catch (Exception err) {
                    err.printStackTrace();
                }
            }
        };
        requestHandler.post(myRunnable);
    }
0
Ravindra babu