I have an Activity with only a stopwatch basically, and when the phone turns, the stopwatch is reset.
Is there an event that causes Activity to be restarted while doing this? I would like to prevent this behavior.
I have an Activity with only a stopwatch basically, and when the phone turns, the stopwatch is reset.
Is there an event that causes Activity to be restarted while doing this? I would like to prevent this behavior.
When you change the device orientation, Android will destroy and re-create Activity
. What is happening is that you are probably starting your timer at onCreate
. As onCreate
is being recalled, the status its timer is being restarted.
I imagine your code looks something like this:
public class CronometroActivity extends Activity {
// ...
// campos da sua classe
// ...
private Cronometro meuCronometro;
// ...
// mais campos da sua classe
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
// inicialização dos elementos da tela
// ...
this.meuCronometro = new Cronometro();
atualizarCronometroDaTela();
}
// demais métodos
}
You may not have a Timer class but other simpler variables to compose the timer state, but the principle is the same.
You should override the onSaveInstanceState
method of Activity
, which is called when Activity is destroyed by the system. The system sends this method a Bundle
, called here estadoDeSaida
, within which you will place the data you want to persist between screen restarts. As you may already know, a Bundle
accepts data from Java primitives, String
s, Serializable
objects, and Parcelable
objects (among some others).
Assuming here that the class Cronometro
implements Parcelable
, the code would look like this:
@Override
public void onSaveInstanceState(Bundle estadoDeSaida) {
super.onSaveInstanceState(estadoDeSaida);
estadoDeSaida.putParcelable("chaveDoMeuCronometro", meuCronometro);
}
After the re-creation, the onCreate
will be called, and will be passed that same Bundle
in the savedInstanceState
parameter, instead of null
that is there when the Activity
is starting normally. From it, you have to remove the data you have placed and re-create your timer.
In this example, it would look like this:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
// inicialização dos elementos da tela
// ...
if (savedInstanceState) {
this.meuCronometro = savedInstanceState.getParcelable("chaveDoMeuCronometro")
} else {
this.meuCronometro = new Cronometro();
}
atualizarCronometroDaTela();
}
In this way, your Activity
is protected from the loss of this information and your timer will not reset.
However, in the specific case of the timer, you may need a more ingenious solution to avoid the loss of seconds in which the timer would freeze, waiting for destruction and re-creation. This solution is for the simplest (and most common) case in which this is not important.
Great solution Pablo Almeida, I used this same, with a Serializable object, so I did not have to implement anything of the Parceable. But you have to cast the object on the return of onCreate ...
@Override
public void onSaveInstanceState(Bundle estadoDeSaida) {
super.onSaveInstanceState(estadoDeSaida);
estadoDeSaida.putSerializable("chaveDoMeuCronometro", meuCronometro);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
// inicialização dos elementos da tela
// ...
if (savedInstanceState) {
this.meuCronometro = (Cronometro) savedInstanceState.getSerializable("chaveDoMeuCronometro")
} else {
this.meuCronometro = new Cronometro();
}
atualizarCronometroDaTela();
}