Resuming CountdownTimer after rotation

被刻印的时光 ゝ 提交于 2019-12-23 00:56:09

问题


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

回答1:


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:

public class Timer extends Service {

    @Override
    public IBinder onBind(Intent i) {
        return null;
    }
    @Override
    public int onStartCommand(Intent i, int flags, int startId) {
        // Put your timer code here
    }
}

You will need to add this line to your manifest (somewhere between the application open/close tags):

<service android:name=".Timer" />

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.):

startService(new Intent(this, Timer.class));



回答2:


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.

Endtime = System.currentTimeMillis + 60000;

then on every instance

TimeRemaining = Endtime - System.currentTimeMillis



回答3:


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



来源:https://stackoverflow.com/questions/11368107/resuming-countdowntimer-after-rotation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!