J'ai rencontré une fonctionnalité très étrange.
Lorsque j'essaye d'exécuter une animation sur le fil principal, cela ne démarre pas. Quand je lance cette animation en utilisant
getView().post(new Runnable() {
@Override
public void run() {
getView().startAnimation(a);
}
});
Ça commence.
J'ai imprimé le CurrentThread
avant de commencer l'animation et les deux imprimer main
.
De toute évidence, il me manque quelque chose ici, car les deux devraient démarrer l'animation sur le fil principal ... Je suppose que lorsque la publication ajoute la tâche à la file d'attente, elle commence à un "moment plus correct", mais j'aimerais savoir ce qui se passe ici plus en profondeur.
EDIT: Permettez-moi de clarifier les choses - ma question est, pourquoi le démarrage de l'animation sur la publication le fait démarrer, lorsque le démarrage de l'animation sur le fil principal ne le fait pas.
AnimationDrawable
! L'Animation
instance ordinaire a commencé à s'animer avec succès sur chaque configuration. AuAnimationDrawable
cas où; lorsque vous essayez de le démarreronCreate
, il ne démarre pas car il n'est pas attaché à la vue à ce moment. Ce n'est donc pas un problème de filetage pourAnimationDrawable
. Peut-être que la même chose s'appliqueAnimation
? developer.android.com/guide/topics/graphics/…Réponses:
post : post entraîne l'ajout du Runnable à la file d'attente des messages,
Exécutable: représente une commande qui peut être exécutée. Souvent utilisé pour exécuter du code dans un thread différent.
run () : Démarre l'exécution de la partie active du code de la classe. Cette méthode est appelée lorsqu'un thread est démarré qui a été créé avec une classe qui implémente Runnable.
code :
getView().startAnimation(a);
dans votre code,
post provoque le Runnable (le code sera exécuté dans un thread différent) pour ajouter la file d'attente de messages.
Donc startAnimation sera déclenché dans un nouveau thread lorsqu'il est extrait de messageQueue
[EDIT 1]
Pourquoi utilisons-nous un nouveau thread au lieu du thread UI (thread principal)?
Fil de discussion de l'interface utilisateur:
Lorsque l'application est lancée, Ui Thread est créé automatiquement
il est chargé de distribuer les événements aux widgets appropriés et cela inclut les événements de dessin.
C'est aussi le fil avec lequel vous interagissez avec les widgets Android
Que se passe-t-il si un utilisateur appuie sur un bouton qui fera une longue opération?
L'interface utilisateur se fige. Le programme peut même planter.
Il enfreint la règle Android qui ne met jamais à jour l'interface utilisateur directement à partir du thread de travail
Android propose plusieurs façons d'accéder au thread d'interface utilisateur à partir d'autres threads.
Comme ci-dessous,
View.post (Exécutable)
Gestionnaire
Pour plus d'informations
http://android-developers.blogspot.com/2009/05/painless-threading.html
http://www.aviyehuda.com/blog/2010/12/20/android-multithreading-in-a-ui-environment/
la source
Cela se fait-il sur onCreate ou onCreateView? Si tel est le cas, l'application peut ne pas être dans un état où la vue est attachée à la fenêtre. De nombreux algorithmes basés sur les métriques View peuvent ne pas fonctionner car des éléments tels que les mesures et la position de View peuvent ne pas avoir été calculés. Les animations Android nécessitent généralement qu'elles s'exécutent via les mathématiques de l'interface utilisateur
View.post met en fait l'animation en file d'attente sur la boucle de message de la vue, donc une fois que la vue est attachée à la fenêtre, elle exécute l'animation au lieu de l'exécuter manuellement.
Vous exécutez en fait des choses sur le thread de l'interface utilisateur, mais à un moment différent
la source
Jetez un œil ici pour une bonne réponse. view.post () est à peu près identique à handler.post (). Il entre dans la file d'attente du thread principal et est exécuté une fois les autres tâches en attente terminées. Si vous appelez activity.runOnUiThread (), il sera appelé immédiatement sur le thread de l'interface utilisateur.
la source
Je pense que le problème pourrait être la méthode du cycle de vie où vous appelez la méthode post (). Le faites-vous dans onCreate ()? si c'est le cas, regardez ce que j'ai trouvé dans la documentation onResume () de l'activité:
https://developer.android.com/reference/android/app/Activity.html#onResume ()
Ainsi, comme l'a dit Joe Plante, la vue n'est peut-être pas prête à démarrer les animations au moment où vous appelez post (), alors essayez de la déplacer vers onResume ().
PD: En fait, si vous déplacez le code vers onResume (), je pense que vous pouvez supprimer l'appel post () puisque vous êtes déjà dans le fil d'interface utilisateur et que la vue devrait être prête à démarrer les animations.
la source
onResume
peut être appelé plusieurs fois (les écrans se mettent en veille, l'activité repoussée en arrière, etc ...) après avoir été initialement lorsque "la vue est prête". S'il est appelé depuisonResume
, un drapeau peut être nécessaire pour suivre la météo pendant laquelle l'animation a déjà été lancée, pour éviter de (re) démarrer plusieurs fois.