2016-05-15 11 views
0

Ich versuche countdowntimer in Android zu verwenden, nachdem ein kleinen Testcode ist sein VerhaltenWarum funktioniert Countdown-Timer nicht in einer eigenständigen Klasse, die keine Aktivität ist? es läuft gut, aber nicht in einer eigenständigen Klasse

new CountDownTimer(30000, 1000) { 

     public void onTick(long millisUntilFinished) { 
      System.out.println("tick"); 
     } 

     public void onFinish() { 
      System.out.println("finish"); 
     } 
    }.start(); 

    System.out.println("done"); 

Wenn ich diese Schnipsel in MainActivity meines Projekt platzieren zu verstehen. Warum ?

Führt Countdown-Timer auch auf Haupt-Thread selbst, oder es erstellt einen anderen Thread?

+0

Machen Sie eine Methode in der Klasse und rufen Sie sie in Aktivität sollte es funktionieren – Haroon

+2

Warum benötigen Sie eigenständige Klasse in Android-Projekten? –

+0

Es funktioniert das gleiche wie AsyncTask, mit einer Methode im Haupt-UI-Thread ausführen, werfen Sie einen genaueren Blick in CountDownTimer-Klasse – Haroon

Antwort

1

Der Code besteht aus 2 Teilen:

CountDownTimer cdt = new CountDownTimer(30000, 1000) { 

    public void onTick(long millisUntilFinished) { 
     System.out.println("tick"); 
    } 

    public void onFinish() { 
     System.out.println("finish"); 
    } 
}; 

Der erste Teil ein CountDownTimer Objekt instanziiert wird, können Sie diesen Code platzieren, wo jeder auf jedem Thread, weil nur Objekt erstellt wurde, es tut nichts.

Der zweite Teil ist:

cdt.start(); 

sollten Sie beachten, dass CountDownTimer von Haupt-Thread starten werden müssen (nennen wir es von onCreate oder onResume ... einer Aktivität). Also, wenn Sie Ihren Code in einer anderen Klasse platzieren, ist es nicht das Problem, Sie müssen sicher, dass start() -Funktion aufgerufen Main Thread.

// Update:

Wissen Sie, die onTick und OnFinish Funktion von CountDownTimer immer auf Hauptthread aufgerufen wird. CountDownTimer wird keinen Thread ausführen.

Es ist sein Code:

public synchronized final CountDownTimer start() { 
    mCancelled = false; 
    if (mMillisInFuture <= 0) { 
     onFinish(); 
     return this; 
    } 
    mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture; 
    mHandler.sendMessage(mHandler.obtainMessage(MSG)); 
    return this; 
} 

Ganz einfach, CountDownTimer wird eine Nachricht von einem Handler senden.

Und das ist Handler:

// handles counting down 
private Handler mHandler = new Handler() { 

    @Override 
    public void handleMessage(Message msg) { 

     synchronized (CountDownTimer.this) { 
      if (mCancelled) { 
       return; 
      } 

      final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); 

      if (millisLeft <= 0) { 
       onFinish(); 
      } else if (millisLeft < mCountdownInterval) { 
       // no tick, just delay until done 
       sendMessageDelayed(obtainMessage(MSG), millisLeft); 
      } else { 
       long lastTickStart = SystemClock.elapsedRealtime(); 
       onTick(millisLeft); 

       // take into account user's onTick taking time to execute 
       long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime(); 

       // special case: user's onTick took more than interval to 
       // complete, skip to next interval 
       while (delay < 0) delay += mCountdownInterval; 

       sendMessageDelayed(obtainMessage(MSG), delay); 
      } 
     } 
    } 
}; 

Der Handler wird eine Verzögerungsmeldung für den Aufruf nächste onTick() oder OnFinish (mit). Also muss es Main Thread (oder Main Looper) verwenden. Wenn Sie möchten, dass es in einem benutzerdefinierten Thread ausgeführt wird, implementieren Sie es auf Ihre Weise neu: D

+1

Meine Frage war, warum sollte der Start() aus Haupt-Thread aufgerufen werden? – jay