14

I have a small test application I am working on which has a timer that updates a textview to countdown from 100 to 0. That works fine, but now I am trying to pause the application if the user presses the back button on the phone and then restart the timer from where they left off when they reopen the app. Here is the code I am using:

@Override
public void onPause()
{
    if(this._timer_time_remaining > 0) {
        this.timer.cancel();
    }
    super.onPause();
    Log.v("Pausing", String.format("Pausing with %d", this._timer_time_remaining));
}

@Override
public void onResume()
{
    Log.v("Resuming", String.format("Resuming with %d", this._timer_time_remaining));

    if(this._timer_time_remaining > 0) {
        start_timer(this._timer_time_remaining);
    }
    super.onResume();
}

The start_timer() method creates a CountDownTimer which updates the textview in the onTick method and updates the this._timer_time_remaining int variable.

CountDownTimer and _timer_time_remaining are both declared at the class level like this:

private CountDownTimer timer;
private int _timer_time_remaining;

From the Log.v() prints I see that the _timer_time_remaining variable has the correct number of seconds stored when onPause is called, but it is set back to 0 when onResume starts. Why does the variable get reset? I thought that the application would continue to run in the background with the same values. Am I missing something? This is all declared in a class that extends Activity.

Thanks in advance!

Note: Edited to clean up the code copying

Blather
  • 1,118
  • 5
  • 15
  • 25

5 Answers5

16

If you take a look at the diagram for Activity lifecycle you'll realize that there are no guarantees about you Activity after onPause is called. Android could kill you Activity without even calling onDestroy. You have to save your state using onSaveInstanceState and restore it using onRestoreInstanceState.

This might be useful.

EDIT:

Lifecycle covers different scenarios. If you have only one Activity pressing Back is equivalent to exiting your application. If you have Activity A which starts activity B then onSaveInstanceState is called for Activity A. When you press back in Activity B it just exits and onRestoreInstanceState is called for Activity A. You are trying to save data between two distinct runs of your application and you need to use some kind of persistent storage for this.

Community
  • 1
  • 1
Nikola Smiljanić
  • 26,745
  • 6
  • 48
  • 60
  • First, thanks for the response. I replaced my onPause method with the onSaveInstanceState(Bundle savedInstancestate) method, but this doesn't seem to be called when I press the back button to leave my application. None of my LogCat messages show up so I don't think it is being called at all. Do I need onPause and onSaveInstanceState implemented? Or should onSaveInstanceState handle it? – Blather Mar 14 '10 at 20:56
  • Documentation explains this: "One example of when onPause() and onStop() is called and not this method is when a user navigates back from activity B to activity A: there is no need to call onSaveInstanceState(Bundle) on B because that particular instance will never be restored, so the system avoids calling it." Pressing Back doesn't call onSaveInstanceState but pressing Home does. – Nikola Smiljanić Mar 14 '10 at 22:21
  • Thanks for responding. I did see that mentioned, but if onSaveInstanceState isn't called when the back button is pressed it won't take care of my issue, will it? I just want the count down timer to stop when the back button is pressed and then restart from the same location when the app is started again from the home screen. I may be misunderstanding, but it doesn't appear that this will accomplish that. Thanks again for the time you've taken to help so far, I am just missing something here I think. – Blather Mar 14 '10 at 22:41
  • You could save the time left in the preferences. – MrSnowflake Mar 17 '10 at 17:30
  • https://stackoverflow.com/a/58504433/5219642 for more detail you can check this – Amit Oct 25 '21 at 11:55
2

This is how I would save the value: (Four lines of code)

SharedPreferences example = getSharedPreferences("example", MODE_PRIVATE);
SharedPreferences.Editor edit = example.edit();
edit.putInt("time_remaining", (Integer)this._timer_time_remaining);
edit.commit();

On resume, do this: (Two lines of code)

SharedPreferences example = getSharedPreferences("example", MODE_PRIVATE);
int time_remaining = example.getInt("time_remaining", 0);

I adapted this from some of my working code, but did not actually test it in this exact format. Search documentation for sharedPreferences to learn how it works.

user425923
  • 21
  • 1
1

I'm not an expert on Android, but just telling from how I expect the timer to behave

this.timer.cancel() :- would cancel the timer, but not pause it

start_timer(this._timer_time_remaining) :- would "restart" the timer, not continue from the last position.

So what you see is correct. Every time the time is started afresh. Find out what is the api to pause the timer (if any).

Nixit Patel
  • 4,435
  • 5
  • 30
  • 57
ashoke
  • 11
  • 1
0

You can simply write the time out to a database or file in onPause and read it back in onResume.

James
  • 1,741
  • 1
  • 9
  • 5
0

You can also try listening to the to key presses ( onKeyDown() ) to intercept the back button and save your data to a SQLite table.

Juan
  • 31
  • 1