2016-05-15 90 views
0

我想在Android中使用countdowntimer,下面是一個小testcode瞭解其行爲爲什麼倒計時器不能在單獨的類上工作?

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"); 

如果我把這個片段在MainActivity我的項目運行良好,但不是在一個獨立的類。爲什麼?

此外,倒計時計時器運行在主線程本身,或者它產生另一個線程?

+0

在類中創建一個方法並在它應該工作的活動中調用它 – Haroon

+2

爲什麼你需要在android項目中使用獨立類? –

+0

它與AsyncTask的工作方式相同,在主UI線程中執行一個方法,仔細觀察CountDownTimer類 – Haroon

回答

1

代碼包括兩個部分:

CountDownTimer cdt = new CountDownTimer(30000, 1000) { 

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

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

第一部分實例化CountDownTimer對象,你可以把這個代碼的任何地方,在任何線程,因爲只有創建對象時,它什麼都不做。

第二部分是:

cdt.start(); 

你應該注意到CountDownTimer必須從(活動的從的onCreate或的onResume稱之爲...)主線程啓動。所以如果你把你的代碼放在另一個類中,這不是問題,你必須確保在Main Thread上調用start()函數。

//更新:

你知道,onTick和CountDownTimer的onFinish功能總是被稱爲在主線程。 CountDownTimer不會運行任何線程。

這是它的代碼:

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

很簡單,CountDownTimer將由處理程序發送消息。

這是處理程序:

// 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); 
      } 
     } 
    } 
}; 

的處理程序將發送延遲消息調用next onTick()或onFinish()。所以它必須使用主線程(或主循環)。如果你想讓它在自定義線程中運行,請用你的方式重新實現:D

+1

我的問題是,爲什麼要從主線程調用start()? – jay