Ich verwende ListenableFuture aus Guava, und eine nette Sache über sie ist, dass ein Pass Executor an die Futures.addCallback
-Methode, dh, um den Callback für einen gegebenen Thread / Executor auszuführen.
In meiner Android-Anwendung möchte ich die asynchrone Ausführung basierend auf ListenableFuture
im UI-Thread starten und einen Rückruf planen können, der auch im UI-Thread ausgeführt wird. Daher möchte ich den UI-Thread-Executor irgendwie an die oben erwähnte Methode Futures.addCallback
übergeben. Wie erreiche ich das?
Oder, mit anderen Worten, ich möchte einen Executor für den UI-Thread haben. Ist es bereits in Android verfügbar, oder, wenn ich meine eigene erstellen muss, wie mache ich das?
BEARBEITEN: Ist es als Erweiterung dieser Frage möglich, dasselbe zu tun, aber nicht nur mit dem UI-Thread, sondern mit einem bestimmten Thread, wo der Aufruf der asynchronen Methode gemacht wird?
Ich wäre glücklich zu wissen, wie ich den gleichen Effekt erzielen kann, ohne auf die Android-spezifischen Sachen wie Handler
und Looper
zu setzen, nur mit reinem Java.
Ich denke, ich habe eine Implementierung gesehen, die das macht. Die Grundidee ist grob
%Vor%Sie können delegieren, um irgendetwas im Hauptthread auszuführen, indem Sie es an einen Handler für den Hauptthread übergeben.
Bearbeiten: Ссылка zum Beispiel
Edit2: Sie können den Handler wie z. SensorManager#registerListener(..., Handler handler)
können Sie tun.
Der Vorteil gegenüber dem Looper des aktuellen Threads ist, dass er explizit angibt, welche Looper
Sie verwenden. In Ihrer Lösung nehmen Sie den Looper von jedem Thread, der new ExecuteOnCaller()
aufruft - und das ist oft nicht der Thread, in dem Sie den Code später ausführen.
Ich wäre glücklich zu wissen, wie ich den gleichen Effekt erzielen kann, ohne auf die Android-spezifischen Sachen wie Handler und Looper zurückgreifen zu müssen, nur mit reinem Java.
Looper
, Handler
und die Nachrichtenwarteschlange hinter dieser ganzen Logik bestehen hauptsächlich aus reinem Java. Das Problem mit einer generischen Lösung ist, dass Sie Code nicht "injizieren" können, um in einem Thread zu laufen. Der Thread muss regelmäßig eine Art von Aufgabenwarteschlange überprüfen, um festzustellen, ob etwas ausgeführt werden muss.
Wenn Sie Code wie
schreiben %Vor%Dann gibt es keine Möglichkeit, diesen Thread etwas anderes zu tun, als ständig "Hallo" zu drucken. Wenn Sie das tun könnten, wäre es, als würden Sie dynamisch einen Sprung zu anderem Code in den Programmcode einfügen. Das wäre IMO eine schreckliche Idee.
%Vor%Auf der anderen Seite ist ein einfacher Thread, der für immer in einer Warteschlange loops . Der Thread könnte dazwischen andere Aufgaben erledigen, aber Sie müssen eine manuelle Überprüfung in den Code einfügen.
Und Sie können es Aufgaben über
senden %Vor% Es ist hier kein spezieller Handler definiert, aber das ist der Kern dessen, was Handler & amp; Looper tun in Android. Mit Handler
in Android können Sie einen Rückruf für eine Message
anstatt nur für eine Runnable
definieren.
Executors.newCachedThreadPool()
und ähnlich machen ungefähr dasselbe. Es gibt nur mehrere Threads, die auf Code in einer einzigen Warteschlange warten.
Als Erweiterung zu dieser Frage, ist es möglich, dasselbe zu tun, aber nicht nur mit UI-Thread, sondern mit einem bestimmten Thread, wo der Aufruf der asynchronen Methode gemacht wird?
Die generische Antwort ist Nein. Nur wenn es eine Möglichkeit gibt, Code in diesen Thread einzufügen.
Basierend auf asnwer von @zapl, hier ist meine Implementierung, die auch die bearbeitete (erweiterte) Frage beantwortet: Ссылка
Ich habe es mir auch ausgedacht, falls der Link eines Tages verfault:
%Vor%Mein Muster dafür wäre so:
%Vor% Verwenden Sie com.google.android.gms.tasks.TaskExecutors.MAIN_THREAD
.
Ein Executor, der den Hauptanwendungs-Thread verwendet.
Quelle: Android-Dokumente
>Die Aufgaben-APIs sind seit der Version 9.0.0 Bestandteil der Google Play-Dienste .
Tags und Links java android guava executorservice