Ich versuche etwas Neues auf Android, für das ich auf den Handler des UI-Threads zugreifen muss.
Ich weiß folgendes:
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
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.
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.
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.
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 :)
Ich schlage vor, folgenden Code zu versuchen:
new Handler(Looper.getMainLooper()).post(() -> {
//UI THREAD CODE HERE
});
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()
}
Lösung:
Handler
mit Looper
aus dem Main Thread: responseHandler und überschreiben Sie die handleMessage
-MethodeRunnable
sendMessage für responseHandler aufsendMessage
führt zum Aufruf von handleMessage in responseHandler.Message
und verarbeiten Sie sie, aktualisieren Sie die BenutzeroberflächeBeispielcode:
/* 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);
}