G'day everyone, welcome back. There's one last thing I want to look at before we finish this
section. To see what it is, I'll get Android Studio to generate an
on destroy stub, at the end of the SettingsDialog. I'll add some logging to
let us see it's being called, when our dialog's destroyed. Okay.
I'll run the app and filter the logcat on SettingsDialog
When I open the settings, we can see it being created in the logcat.
I'll add the comment rotating to the logcat, to make it easier to see when things happen.
Then I'll rotate the device. There's no surprises there, if you've studied the
fragment life cycle. AddDialog is a DialogFragment, and it has the same life
cycle as other fragments. We can see it being destroyed, then recreated.
That's not a huge problem. Android recreates it and attaches it to
the activity again, but it can be inefficient. It's possible to prevent a
fragment being destroyed like this. It's not something you should do often, but a
retained fragment can be useful sometimes. Generally, you'll probably use
a view model to retain state, as we've seen. But if you're not using a view
model for some reason, and your fragment contains data that's expensive to fetch
again, then you can set it to retain its state, and not be destroyed when its
activity is. To do that, we just set retain instance to true, in onCreate.
I'll repeat the previous test. Run the app, and go into settings. There's our
dialog being created. I'll add the comment rotating to the logcat again,
then rotate the device. This time, onDestroy doesn't get called. The Dialog
Fragment isn't destroyed. We also don't get the onCreate logged, because the
DialogFragment isn't recreated. Its view still has to be created, of course, and if
you're not sure why, then watch the videos on the fragment lifecycle again.
Alright, we've saved a bit of processing there, and the destroyed fragment no
longer has to be garbage collected. So this is a small improvement in
efficiency. It has another use here. It makes it easier to fix a bug in our code.
To see the bug, watch what happens when I start to change the day and time.
I'll set them to Sunday and zero, to make it easier to spot,
then I'm gonna tap OK to save the changes. Well now you're back into
settings, we've got Sunday as the first day, with zero as the number of seconds
to ignore. I'll change them to Monday,
and drag the slider to the middle. When I rotate the device,
we've lost our values. They've gone back to Sunday and zero. We could implement
the OnSavedInstanceState and onRestore InstanceState functions to fix that, but
because our Dialogfragment isn't being destroyed, it's much easier to just avoid
setting the values when the device is rotated. Looking at onViewStateRestored,
we know that savedInstanceState will be null when the dialog's
first created. We can test that, and only change a spinner and the SeekBar
if the savedInstance is null.
Now, we read the values and set the widget when our dialog's first created,
but don't do that again when the device is rotated. I'll repeat the test.
Run the app again, go into settings and we've got Sunday and 0 as the values. Once again,
I'll change them to Monday and somewhere in the middle. Now when I rotate the
device, the DialogFragment's retained its state, and everything's
where it should be. We've checked in onViewStateRestored,
and don't reset the widgets to the saved values again. They keep the values they
had, before the device was rotated. Alright, that's the end of our Settings
Dialog, and of this section. We're not using the settings yet, but it makes
sense to allow them to be changed, before we write the code that uses them. In the
next section, we'll create the timings table and get the app to time the tasks.
I'm looking forward to seeing you then.