2011-05-27 125 views
3

我一直在解決很多問題,嘗試暫停和取消暫停計時器,並且如果我將方向鎖定爲縱向或橫向,它就起作用,但那不完全是我想要做的。當然,當你改變方向時,onCreate方法被調用,所以即時取消我的時間任務並將其設置爲null,但是在多次運行方向後,它不再取消時間任務。我查看了其他人在這裏的問題,但似乎沒有答案對我的問題。繼承人我的代碼。它目前有點馬虎,因爲我一直在盡我所能去實現它。Android - 如何停止和暫停計時器

public class singleTimer extends Activity implements OnClickListener { 

private Integer setTime = 0; 
private Integer tmrSeconds = 0; 
private Integer tmrMilliSeconds = 0; 
private Timer myTimer = new Timer(); 
private TimerTask myTimerTask; 
private TextView timerText; 
private boolean isPaused = true; 

@Override 
public void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.single_timer); 
    Bundle extras = getIntent().getExtras(); 
    setTime = extras.getInt("com.bv.armyprt.timer_duration"); 
    if (myTimerTask != null) { 
     myTimerTask.cancel(); 
     myTimerTask = null; 
    } 
    if (savedInstanceState != null) { 
     if (savedInstanceState.getInt("tmrSeconds") == 0) { 
      tmrSeconds = setTime; 
     } else { 
      tmrSeconds = savedInstanceState.getInt("tmrSeconds"); 
      tmrMilliSeconds = savedInstanceState.getInt("tmrMilliseconds"); 

      if (isPaused == false) { 
       myTimer = new Timer(); 
       myTimerTask = new TimerTask() { 
        @Override 
        public void run() { 
         TimerMethod(); 
        } 
       }; 
       myTimer.schedule(myTimerTask, 0, 100); 
      } 

     } 
    } else { 
     tmrSeconds = setTime; 
    } 
    timerText = (TextView)findViewById(R.id.timerText); 
    timerText.setText(String.format("%03d.%d", tmrSeconds, tmrMilliSeconds)); 

    TextView timerDesc = (TextView)findViewById(R.id.timerDescription); 
    timerDesc.setText("Timer for: " + setTime.toString()); 
    Button startButton = (Button)findViewById(R.id.timerStart); 
    Button stopButton = (Button)findViewById(R.id.timerStop); 
    Button closeButton = (Button)findViewById(R.id.timerClose); 
    closeButton.setOnClickListener(this); 
    startButton.setOnClickListener(this); 
    stopButton.setOnClickListener(this); 

} 

@Override 
public void onClick(View v) { 
    // TODO Auto-generated method stub 
    switch (v.getId()) { 
    case (R.id.timerStart): 
     isPaused = false; 
     myTimer = new Timer(); 
     myTimerTask = new TimerTask() { 
      @Override 
      public void run() { 
       TimerMethod(); 
      } 
     }; 
     myTimer.schedule(myTimerTask,0, 100); 
     break; 

    case (R.id.timerStop): 
     isPaused = true; 
     myTimerTask.cancel(); 
     myTimerTask = null; 
     myTimer.cancel(); 

     break; 

    case (R.id.timerClose): 
     onDestroy(); 
     this.finish(); 
     break; 
    } 

} 
private void TimerMethod() 
{ 
    //This method is called directly by the timer 
    //and runs in the same thread as the timer. 
    //We call the method that will work with the UI 
    //through the runOnUiThread method. 
    this. 
    tmrMilliSeconds--; 
    this.runOnUiThread(Timer_Tick); 
} 

private Runnable Timer_Tick = new Runnable() { 
    public void run() { 

    //This method runs in the same thread as the UI.    
     if (tmrSeconds > 0) { 
      if (tmrMilliSeconds <= 0) { 
       tmrSeconds--; 
       tmrMilliSeconds = 9; 
      } 
     } else { 
      Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); 
      v.vibrate(1000); 
      myTimer.cancel(); 
      tmrSeconds = setTime; 
      tmrMilliSeconds = 0; 
      isPaused = true; 
     } 

    //Do something to the UI thread here 
     timerText.setText(String.format("%03d.%d", tmrSeconds, tmrMilliSeconds)); 
    } 
}; 

@Override 
public void onSaveInstanceState(Bundle savedInstanceState){ 
    savedInstanceState.putInt("setTimer", setTime); 
    savedInstanceState.putInt("tmrSeconds", tmrSeconds); 
    savedInstanceState.putInt("tmrMilliseconds", tmrMilliSeconds); 

    super.onSaveInstanceState(savedInstanceState); 
} 

@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) { 
    super.onRestoreInstanceState(savedInstanceState); 

    setTime = savedInstanceState.getInt("setTimer"); 
    tmrSeconds = savedInstanceState.getInt("tmrSeconds"); 
    tmrMilliSeconds = savedInstanceState.getInt("tmrMilliSeconds"); 
} 
} 
+0

「當然,在改變方向時調用onCreate方法」 - 你意識到它比這稍微複雜一點?當方向改變時,活動被完全銷燬,然後重新創建。 – Squonk 2011-05-27 23:24:58

回答

11

,你可以簡單地添加一個布爾變量

boolean stopTImer = false ; 

,並在TimerTask的,做這樣的事情:

@Overrride 
public void run(){ 
if(!stopTimer){ 
//do stuff ... 
//... 
} 

,當你想停止它,把布爾到true

+0

那就是我最終做的,即時通訊使用isPaused布爾值,並在運行方法中檢查它。感謝您的幫助 – Shaun 2011-05-28 03:28:11

+0

很高興聽到它,歡迎您:) – Houcine 2011-05-28 14:13:32

2

您應該在onStop期間停止計時器。 Android可能會創建Activity的另一個實例,並且當您更改方向時,您將失去對之前計時器(任務)的引用。

綁定到活動的所有對象都遵循活動生命週期。這意味着如果要保留它們(即使該活動被刪除)(這可能會經常發生),您必須將引用存儲到別處的對象。

+0

這對我試圖做什麼有部分作用,但我需要能夠停止並恢復計時器。 – Shaun 2011-05-28 03:27:41

+0

這就是爲什麼你應該在更全球的地方存儲定時器引用。隨着你的實現,如果活動被刪除並重新實例化,你可能會失去定時器引用。由於您在onCreate期間暫停計時器(或設置暫停計時器),您不會暫停原始計時器,而是暫停新計時器。您應該至少在onStop期間設置暫停標誌以防止原始計時器流氓。 – marsbear 2011-05-28 12:53:10