2017-03-06 2 views
1

Ce que je veux faire:Android: quels sont les avantages et les inconvénients de l'utilisation d'un CountDownTimer vs Thread.sleep()?

Je suis désireux d'utiliser un travailleur thread de mettre à jour régulièrement un champ de texte dans l'interface utilisateur de cette discussion. Disons, toutes les 2 secondes pendant 30 secondes. J'ai besoin que le compte à rebours de 30 secondes se produise même si l'application n'est pas au premier plan. Pour l'instant, j'évalue les mérites de deux approches différentes (utilisant toutes deux des threads de travail) pour implémenter ceci. Je ne vais pas poster le code complet ici pour simplifier les choses et aussi parce que je ne demande pas de trouver un problème dans mon code. Les deux solutions fonctionnent bien.

Solution # 1 - utiliser Thread.sleep() dans une boucle for

for (int i = 30; i > 0; i-=2) { 
    Message msg = mHandler.obtainMessage(MSG_ID, i, 0); 
    msg.sendToTarget(); 

    try { 
     Thread.sleep(2000); 
    } catch(Throwable t) { 
     // catch error 
    } 

} 

Solution # 2 - utiliser CountDownTimer

Looper.prepare() 

new CountDownTimer(30000, 2000) { 
    public void onTick(long millUntilFinish) { 
     int seconds = (int)(millUntilFinish); 
     Message msg = mHandler.obtainMessage(MSG_ID, seconds, 0); 
     msg.sendToTarget(); 
    } 

    public void onFinish() { 
     // left blank for now 
    } 
}.start(); 

Looper.loop(); 

Ma question

Whil Les deux fonctionnent, je veux savoir s'il y a une façon «meilleure» ou «préférée» de le faire pour une raison quelconque. Je pense qu'il peut y avoir des domaines en particulier dans la vie de la batterie, mais aussi dans la performance, la précision ou la conception de code où une solution est meilleure que l'autre.

Ce que je l'ai fait jusqu'à présent pour répondre à cette question

Ma propre évaluation si loin de la lecture this SO question et de documentationCountDownTimer sont que puisque les deux sont exécutés sur le travailleur-fil, les deux ont pas la possibilité de l'ANR . Les deux solutions garantiront également qu'une "mise à jour" n'aura lieu qu'une fois la mise à jour précédente terminée. Malheureusement, c'est tout ce que j'ai et j'espère que n'importe qui peut m'aider ou me guider vers une question perspicace et/ou similaire que j'ai pu ignorer ou que je n'ai pas réussi à trouver.

J'écris cette question avec un peu de prudence car je n'ai pas de code problématique qui nécessite un débogage mais je pense que cela tombe dans SO's catégorie d'un "problème de programmation spécifique", qui n'a pas été répondu, et non inclus dans la liste des réponses hors sujet.

Répondre

1

1.Calling Thread.sleep met en pause l'exécution du fil pendant un certain temps alors que le compte à rebours utilise en fait callbacks pour notifier les événements d'expiration de la minuterie et est asynchrone dans la nature.

2.Si l'exécution du thread s'arrête, vous ne pourrez pas utiliser ce thread spécifique pour une autre opération avant le délai d'attente de veille, par conséquent, il n'est pas recommandé d'utiliser l'approche Thread.sleep. Évidemment, il y a un chargement sur cpu s'il doit reprendre l'exécution du thread et le mettre en pause. Comme dans le cas du compte à rebours, le thread continue d'être en exécution/inactif et comme les événements se produisent.

0
call Thread.sleep() method is not good idea beacuse ii sleep the UI Thread and disadvantage of CountDownTimer is, It Will stop when ur screen is off hence instead of this two try Handler for that like this 


Handler handler; 
    Runnable runnable; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     handler = new Handler(); 
     Runnable runnable = new Runnable() { 
      @Override 
      public void run() 
      { 
       if (dataReceived) 
       { 
        cancelHandler(); 
       } 
      } 
     }; 
     handler.postDelayed(runnable, 100); 
    } 

    public void cancelHandler() 
    { 
     handler.removeCallbacks(runnable); 
    }