Reputation: 48
I'm an experienced .NET dev, but this is my first Android app and it's driving me nuts!
It's a countdown timer which works fine, but when you rotate the screen it reinitialised the activity which zeroed and stopped the count down.
This is what I tried; I got rid of the CountDownTimer object and instead created a class internal to the activity which extended AsyncTask so it ran on a separate thread... No change. I figured being an internal class it's being reinitialised with the activity.
Here's what I tried next; I made the class an external one. The Activity passes its Context to the class and the onProgressUpdate & onPostExecute run public functions on the context to update the activity's UI. Again, this works fine until you rotate it... Aaaargh!
However, I discovered that the async class is still running but the UI doesn't change because (I think) the activity now has a different context to the one the async class has reference to.
So that's where I am. Each solution fixes one problem & creates another. Do I need to somehow maintain the context or am I starting to chase my own tail?
Any help will be gratefully appreciated!
Ta. Barry
Upvotes: 3
Views: 183
Reputation: 8774
In your CountDownTimer
implement onTick
:
@Override
public void onTick(long millisUntilFinished) {
// something like this:
this.millisUntilFinished = millisUntilFinished;
}
In your Activity
implement onSaveInstanceState
:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// something like this:
savedInstanceState.putLong("millisUntilFinished", millisUntilFinished);
}
also in onCreate
and onStart
re-setup your CountDownTimer
:
@Override
public void onCreate(Bundle savedInstanceState) {
// ...
if (savedInstanceState != null) {
millisUntilFinished = savedInstanceState.getLong("millisUntilFinished");
}
}
@Override
public void onStart() {
super.onStart();
timer = new MyCountDownTimer(millisUntilFinished, 100);
timer.start();
}
Don't copy this code verbatim, there are a few details missing/assumptions made that will be different in your code, but it could look something like this.
Upvotes: 2
Reputation: 95
The solution from Try_me34 is good, but here are some other ways to save and restore data (can't post them as a comment):
Try overriding the onPause
method and save the process to a secondary class (a Timer, maybe) and then restore it overriding onResume
.
Another option is to save it as a preference:
SharedPreferences.Editor editor = getSharedPreferences("nameOfFile", MODE_PRIVATE).edit();
editor.putInt("name", value);
editor.putString("nameForString", value);
And then load it:
SharedPreferences prefs = getSharedPreferences("nameOfFile", MODE_PRIVATE);
int i = prefs.getInt("tag", 0);
String s = prefs.getString("tag", "defaultValue");
Upvotes: 1
Reputation: 5506
However, I discovered that the async class is still running but the UI doesn't change because (I think) the activity now has a different context to the one the async class has reference to.
Nice guess. You have to handle the Activity's lifecycle
, if you want to keep the computed data since whenever you rotate the device, the activity is getting recreated thus onCreate()
is getting called without saving the previous computed data. You have to override onSaveInstanceState(Bundle savedInstanceState)
and onRestoreInstanceState()
in order to save your computations. Take a look at the Activity's LifeCycle documentation and Reto Meier's answer, I think it will solve your problem.
Upvotes: 1