2016-11-18 1 views
1

J'ai essayé de créer un chronomètre personnalisé qui compte dans android. Il doit être assez précis jusqu'à 0.1s et avec la disposition et les images personnalisées pour l'exemple de chiffres: DIGITS.Minuterie Android/Chronomètre avec interface utilisateur personnalisée et performances satisfaisantes

Il doit également pouvoir s'exécuter en arrière-plan une fois l'application réduite ou fermée. Pour être plus précis, pour forcer l'application à rester ouverte pendant que la minuterie est activée (je ne sais pas comment y parvenir). Jusqu'à présent, j'ai essayé d'utiliser Handlers, Runnables, scheduledExecutorService et la classe chronomètre android. Les gestionnaires ont eu des problèmes avec les performances, mâchant 45%> l'utilisation du processeur (je pense que c'était parce que l'interface utilisateur continuellement mise à jour?). J'ai réussi à le faire fonctionner en utilisant schedExecutorService avec des performances modestes, mais il reste difficile de continuer en arrière-plan ou pendant les changements d'orientation. J'essaie de créer quelque chose de similaire au chronomètre par défaut de l'horloge du HTC One M7. Cela fonctionne en arrière-plan et pendant les changements d'orientation sans perdre de temps.

La minuterie sera dans son propre fragment dans une activité à l'aide d'un ViewPager et de la disposition des onglets coulissants.

C'est le runnable pour le chronomètre

public Runnable run() { 

    return new Runnable() { 
     @Override 
     public void run() { 

      centiseconds++; 
      if (centiseconds > 9) { 
       centiseconds = 0; 
       seconds++; 
      } 
      if (seconds > 59) { 
       seconds = 0; 
       minutes++; 
      } 
      if (minutes > 59) { 
       minutes = 0; 
       hours++; 
      } 

      getActivity().runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 

        updateCustomUI(); 

       } 
      }); 
     } 
    }; 
} 

Dans le fragment i puis initialisez le scheduledExecutorService

ScheduledFuture scheduledFuture; 
ScheduledExecutorService scheduledExecutorService; 

Pour démarrer la minuterie

scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(run(), 0, 100, TimeUnit.MILLISECONDS); 

et pour l'arrêter

scheduledFuture.cancel(true); 
+0

Votre code échouera lorsque l'écran est éteint ou que votre application fonctionne en arrière-plan car Android l'arrête et votre code de comptage s'arrête également. Utilisez CountDownTimer au lieu de votre propre code de second comptage. – Robert

+0

Cela ne serait utile que pour compter à droite? Comment pourrais-je l'implémenter pour le comptage UP? (comme dans un chronomètre). –

+0

Lisez la documentation puis vous verrez qu'il existe une méthode 'onTick()' qui peut être déclenchée tous les 1000 millisecondes. – Robert

Répondre

0

Dans ce cas, vous pouvez utiliser IntentService avec ResultReciver

+0

oui, comme je l'ai dit dans ma question, j'ai déjà essayé d'utiliser des gestionnaires. J'ai trouvé que leur timing n'était pas assez cohérent pour la minuterie que je voulais créer. Cela ne résoudrait pas non plus le problème de pouvoir exécuter en arrière-plan pendant que l'application est en pause ou arrêtée. Ou ai-je oublié quelque chose? –

+0

J'ai édité ma réponse – GreenRobo

+0

Je n'ai pas encore d'objectifs et de diffusion/récepteurs de résultats. Je vais l'apprendre et l'essayer. Je verrai où cela me mènera. –

0

J'ai essayé d'utiliser les classes Android AnimationDrawable mais la performance était au sujet de la même et androidDevelopers n'a pas eu beaucoup de documentation à ce sujet comme la précision et le potentiel de surcharger etc.

J'ai donc décidé que ma mise en œuvre était la plus efficace, avec un maximum de 10% et une moyenne de 7% sur mon HTC One M7.

Bien que je ne sache pas si j'ai implémenté correctement la classe Animation lorsque je l'ai essayée, si quelqu'un sait exactement comment cela fonctionne, alors n'hésitez pas à me le faire savoir.

Le démarrage du scheduledExecutorService en utilisant une initialisation différente semble avoir résolu le travail en arrière-plan.

Auparavant j'ai lancé à l'aide

scheduledExecutorService= Executors.newSingleThreadScheduledExecutor();

maintenant j'utiliser

scheduledExecutorService= Executors.newScheduledThreadPool(16); 

Tout autre nombre arbitraire de l'threadpool semble fonctionner très bien, je avons encore pour l'optimiser et trouver le bon num Cela permet au programme scheduledExecutorService de s'exécuter en arrière-plan en ayant plus de threads à partir desquels il peut tirer si certains sont détruits lorsque l'activité ou le fragment est détruit.