Ich bin auf eine sehr seltsame Funktion gestoßen.
Wenn ich versuche, eine Animation im Hauptthread auszuführen, wird sie nicht gestartet. Wenn ich die Animation mit ausführe
getView().post(new Runnable() {
@Override
public void run() {
getView().startAnimation(a);
}
});
Es fängt an.
Ich habe die CurrentThread
vor dem Start der Animation gedruckt und beide drucken main
.
Offensichtlich fehlt mir hier etwas, da beide die Animation im Haupt-Thread starten sollten ... Ich vermute, dass der Beitrag die Aufgabe zur Warteschlange hinzufügt und zu einem "korrekteren Zeitpunkt" beginnt, aber ich würde es gerne wissen Was passiert hier in größerer Tiefe.
EDIT: Lassen Sie mich die Dinge klären - meine Frage ist, warum das Starten der Animation auf Post dazu führt, dass sie gestartet wird, wenn das Starten der Animation auf dem Haupt-Thread dies nicht tut.
AnimationDrawable
! Die normaleAnimation
Instanz wurde bei jedem Setup erfolgreich animiert. Für denAnimationDrawable
Fall; Wenn Sie versuchen, es zu startenonCreate
, wird es nicht gestartet, da es in diesem Moment nicht an die Anzeige angehängt ist. Es ist also kein Threading-Problem fürAnimationDrawable
. Vielleicht gilt das Gleiche fürAnimation
? developer.android.com/guide/topics/graphics/…Antworten:
post : post bewirkt, dass Runnable zur Nachrichtenwarteschlange hinzugefügt wird.
Runnable: Stellt einen Befehl dar, der ausgeführt werden kann. Wird häufig verwendet, um Code in einem anderen Thread auszuführen.
run () : Startet die Ausführung des aktiven Teils des Klassencodes. Diese Methode wird aufgerufen, wenn ein Thread gestartet wird, der mit einer Klasse erstellt wurde, die Runnable implementiert.
Code :
getView().startAnimation(a);
in Ihrem Code,
post bewirkt, dass Runnable (der Code wird in einem anderen Thread ausgeführt) die Nachrichtenwarteschlange hinzufügt.
StartAnimation wird also in einem neuen Thread ausgelöst, wenn es aus der messageQueue abgerufen wird
[EDIT 1]
Warum verwenden wir einen neuen Thread anstelle des UI-Threads (Haupt-Thread)?
UI-Thread:
Wenn die Anwendung gestartet wird, wird der UI-Thread automatisch erstellt
Es ist für den Versand der Ereignisse an die entsprechenden Widgets verantwortlich, einschließlich der Zeichenereignisse.
Es ist auch der Thread, mit dem Sie mit Android-Widgets interagieren
Was passiert, wenn ein Benutzer eine Taste drückt, die longOperation ausführt?
Die Benutzeroberfläche friert ein. Das Programm kann sogar abstürzen.
Es verstößt gegen die Android-Regel, die die Benutzeroberfläche niemals direkt vom Arbeitsthread aus aktualisiert
Android bietet verschiedene Möglichkeiten, um von anderen Threads aus auf den UI-Thread zuzugreifen.
Wie unten,
View.post (Runnable)
Handler
Für mehr Information
http://android-developers.blogspot.com/2009/05/painless-threading.html
http://www.aviyehuda.com/blog/2010/12/20/android-multithreading-in-a-ui-environment/
quelle
Wird dies in onCreate oder onCreateView durchgeführt? In diesem Fall befindet sich die App möglicherweise nicht in einem Zustand, in dem die Ansicht an das Fenster angehängt ist. Viele auf View-Metriken basierende Algorithmen funktionieren möglicherweise nicht, da Dinge wie die Messungen und die Position der View möglicherweise nicht berechnet wurden. Für Android-Animationen müssen sie normalerweise die UI-Mathematik durchlaufen
View.post stellt die Animation tatsächlich in die Nachrichtenschleife der Ansicht ein. Sobald die Ansicht an das Fenster angehängt wird, wird die Animation ausgeführt, anstatt sie manuell ausführen zu lassen.
Sie führen tatsächlich Dinge auf dem UI-Thread aus, jedoch zu einem anderen Zeitpunkt
quelle
Werfen Sie einen Blick hier für eine gute Antwort. view.post () ist so ziemlich dasselbe wie handler.post (). Es wird in die Haupt-Thread-Warteschlange gestellt und ausgeführt, nachdem die anderen ausstehenden Aufgaben abgeschlossen sind. Wenn Sie activity.runOnUiThread () aufrufen, wird es sofort im UI-Thread aufgerufen.
quelle
Ich denke, das Problem könnte die Lebenszyklusmethode sein, bei der Sie die post () -Methode aufrufen. Machst du es in onCreate ()? Wenn ja, schauen Sie sich an, was ich in der onResume () -Dokumentation der Aktivität gefunden habe:
https://developer.android.com/reference/android/app/Activity.html#onResume ()
Wie Joe Plante sagte, ist die Ansicht möglicherweise nicht bereit, Animationen zu starten, sobald Sie post () aufrufen. Verschieben Sie sie daher nach onResume ().
PD: Wenn Sie den Code nach onResume () verschieben, können Sie den Aufruf von post () entfernen, da Sie sich bereits im UI-Thread befinden und die Ansicht zum Starten von Animationen bereit sein sollte.
quelle
onResume
kann mehrmals aufgerufen werden (Bildschirme werden in den Ruhezustand versetzt, Aktivität in den Backstack verschoben usw.), nachdem "die Ansicht fertig ist". Wenn von aufgerufenonResume
, wird möglicherweise eine Flagge benötigt, um das Wetter zu verfolgen, bei dem die Animation bereits gestartet wurde, um ein mehrmaliges (erneutes) Starten zu vermeiden.