I have a CountdownTimer that counts down from 60 seconds. This CountdownTimer works by setting a textView to the remaining milliseconds, but whenever i rotate my device, the CountdownTimer gets reset.
I know this happens because the Activity gets restarted on rotation. So i tried saving the time remaining in a bundle and then restoring it, after the Activity was restarted.
long transferValue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_playtimemode);
Log.d("Debug", "onCreate: " + transferValue);
long setTime = 60000;
long difference = setTime - transferValue;
new CountDownTimer(difference, 1000) {
public void onTick(long millisUntilFinished) {
millisUntilFinishedToSave = millisUntilFinished;
tvCountdown.setText("" + millisUntilFinished / 1000);
}
public void onFinish() {
tvCountdown.setText("done!");
}
}.start();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("millisKey", millisUntilFinishedToSave);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
transferValue = savedInstanceState.getLong("millisKey");
Log.d("Debug", "onRestoreInstanceState(): " + transferValue);
}
This however doesn't work. I am intializing transferValue at the top of this code (hence it returning 0), but how can i else save the data from the savedInstanceState to the CountdownTimer?
07-06 20:21:30.038: D/Debug(28995): onCreate: 0
07-06 20:21:30.043: D/Debug(28995): onRestoreInstanceState(): 55994
I would give your timer it's own thread. Your timer is being stopped because it's on the UI thread (as you stated) and when the UI redraws the Activity is re-initialized. All long running processes should have their own thread. Rule of thumb: get out of the UI thread as soon as possible.
Here is an example of using a Service. This service will start when called and stay in memory regardless of screen orientation changes or even activity focus changes.
Here is the service:
You will need to add this line to your manifest (somewhere between the application open/close tags):
Then you can start the service at any time by using this (it's important to note that you can start it over and over again, the recursive calls do not make a new service.):
Use System.currentTimeMillis to get the current system time, then add 60000 milliseconds to the time and store that as an end time. Then any time you have to change anything, just compare System.currentTimeMillis to the EndTime.
then on every instance
The accepted answer makes the thing very complex. You can do it in a simpler way. The problem in your code is that Activity gets created on rotation (see Activity Lifecycle), so does the CountdownTimer instance.
I could write the whole example code but there is a nice answer from @Drew here: Android Innerclass TextView reference when activity resumes