2011-03-15 2 views
0

J'ai une application qui lit un fichier mp3 et j'essaie de mettre à jour un champ personnalisé en synchronie avec certains moments que nous avons tabulés pour la lecture du son (un peu comme un effet karaoké). J'utilise un Handler pour planifier ces mises à jour. Dans ma classe de champ personnalisé, je définis un Runnable qui est censé exécuter la mise à jour au bon moment:Problème de synchronisation du son et de l'affichage

private final Runnable mTrigger = new Runnable() { 
    @Override 
    public void run() { 
     int now = mPlayer.getCurrentPosition(); 
     if (mState == STATE_PLAYING && mUpdateAction != null) { 
      if (mTriggerTime - now > MAX_PREMATURE_TRIGGER) { 
       // Sound is lagging too much; reschedule this trigger 
       mHandler.postDelayed(this, mTriggerTime - now); 
      } else { 
       // Run the update 
       mUpdateAction.run(); 
      } 
     } 
    } 
}; 

Quand j'appelle mPlayer.start() je planifie la première mise à jour en appelant mHandler.postDelayed(mTrigger, timeToFirstUpdate). Chaque action de mise à jour décide de la prochaine mise à jour et la planifie (en appelant le mHandler.postDelayed(mTrigger, timeToNextUpdate)). Les temps de mise à jour sont généralement espacés de quelques centaines de millisecondes. Le problème est que, alors que certaines mises à jour se produisent rapidement aux heures programmées, d'autres peuvent être retardées de 200 millisecondes ou plus, ce qui est assez perceptible pour l'utilisateur. Je ne fais rien dans mon application entre ces mises à jour autres que la lecture du son. (Aucun thread de travail d'arrière-plan, aucune autre mise à jour d'affichage.) Les retards semblent être aléatoires et varient considérablement à chaque fois.

Je ne pensais pas que le timing pour postDelayed serait aussi imprécis! Je ne sais pas si c'est un problème d'émulateur ou un problème avec mon approche. Est-ce que la lecture du son bloque le timing de la boucle de thread de l'interface utilisateur? Dois-je déplacer la synchronisation dans un fil d'arrière-plan (et est-il sûr d'appeler mPlayer.getCurrentPosition() à partir d'un fil de fond)? Autre chose?

Répondre

0

Après beaucoup d'expériences, il semble que le problème soit l'émulateur. Quand j'ai tout couru sur un poste de travail plus rapide, le problème semble avoir disparu.