1
00:00:03,760 --> 00:00:08,559
Welcome back. I'll finish this section by
seeing what happens when the user's phone

2
00:00:08,559 --> 00:00:13,869
battery dies. It's easy to test that
using the emulator. Make sure you're

3
00:00:13,869 --> 00:00:21,200
timing a task, then use the icon on the
sidebar to open the extended controls window.

4
00:00:21,200 --> 00:00:25,550
But before I continue I'd better give you a warning.

5
00:00:25,550 --> 00:00:31,620
Don't do this with an emulator that you
want to keep. It'll probably go okay, but

6
00:00:31,620 --> 00:00:35,640
you could end up with an emulator that
you can't start up. Emulators are

7
00:00:35,640 --> 00:00:39,750
disposable things and you can always
create a new one, but if you've spent a lot

8
00:00:39,750 --> 00:00:43,800
of time configuring your emulator, then
you might want to create a new one for

9
00:00:43,800 --> 00:00:48,760
this step. That's what I've done. Alright.

10
00:00:48,760 --> 00:00:54,600
The emulator is running and a task was
being timed. I'll clear the logcat

11
00:00:54,600 --> 00:00:58,160
because we want to see what gets logged.

12
00:01:08,260 --> 00:01:20,960
In the extended controls, select battery.
Set the charger connection to none,

13
00:01:20,960 --> 00:01:26,140
the emulator default to an AC charger, and we'll set it back to that when we're finished.

14
00:01:26,140 --> 00:01:30,170
Our emulator's now running on battery,
or to be more accurate, it's behaving as

15
00:01:30,170 --> 00:01:41,960
if it is. To simulate the battery dying,
drag the charge level slider all the way to zero.

16
00:01:41,960 --> 00:01:47,260
Okay, our battery's died, and the
emulator shuts down, just like a real

17
00:01:47,260 --> 00:01:52,400
phone would do. Before we start it up
again, let's examine the logcat.

18
00:01:52,400 --> 00:01:57,580
At the end, we can see MainActivity and
MainActivityFragment, going through the

19
00:01:57,590 --> 00:02:03,440
destroy phases of their life cycle. for
both of them, we get onPause followed by

20
00:02:03,440 --> 00:02:08,149
onStop. Depending on any warning
dialogues we may have appeared as the

21
00:02:08,149 --> 00:02:13,790
battery died, you may see onPause
followed by onResume, first. That's fine -

22
00:02:13,790 --> 00:02:20,630
what's important are the final onPause
and onStop. Because it's Android that killed

23
00:02:20,630 --> 00:02:27,920
the fragment and the activity, you should
also see onSaveInstanceState being called.

24
00:02:27,920 --> 00:02:32,360
That's interesting - when the user
starts the app again, you may think that

25
00:02:32,360 --> 00:02:36,590
instance state should be restored. This
should behave like a device rotation, in

26
00:02:36,590 --> 00:02:42,860
other words. Unfortunately, it doesn't, and
you'll get a null bundle in onCreate

27
00:02:42,860 --> 00:02:47,220
when the app is relaunched. The app will
behave as though it's been closed by the

28
00:02:47,240 --> 00:02:52,600
user, but they'll probably expect that. if
they let their phone run out of battery.

29
00:02:52,600 --> 00:02:58,130
Alright, onPause and onStop were
called, and we can reliably use them to

30
00:02:58,130 --> 00:03:02,540
store user data, if we want. There's
something missing from logcat, though.

31
00:03:02,540 --> 00:03:07,489
Have you spotted it? When you rotate a
phone, the ViewModel doesn't get

32
00:03:07,489 --> 00:03:12,440
destroyed. The ViewModel survives things
like rotation and continues to exist in

33
00:03:12,440 --> 00:03:17,419
memory. Unfortunately, though, the memory
has been cleared. The device currently

34
00:03:17,420 --> 00:03:20,700
has no power because it's battery died.

35
00:03:20,700 --> 00:03:27,460
That's important to us, because the entry that's missing from logcat, is the TaskTimerView Model's

36
00:03:27,460 --> 00:03:31,880
onCleared function getting
called. At the moment, all we're doing in

37
00:03:31,880 --> 00:03:36,220
there is unregistering the content
observer to avoid a memory leak.

38
00:03:36,220 --> 00:03:40,460
Obviously, a memory leak isn't an issue
when the phone power's down. Where it

39
00:03:40,460 --> 00:03:45,770
might be an issue, is if we decided to
use onCleared to persist some data, such as

40
00:03:45,770 --> 00:03:51,500
the current timing. It's fine to store
data in the activity, or fragment on

41
00:03:51,500 --> 00:03:56,920
Pause or onStop functions. We've just
seen them being called in the logcat.

42
00:03:56,920 --> 00:04:01,550
Don't use a ViewModel's onCleared
function to persist data. If you

43
00:04:01,550 --> 00:04:05,570
rely on it being called, horrible things
will happen when the battery dies,

44
00:04:05,570 --> 00:04:09,770
or Android has to kill the app for other
reasons. If you decided to use a Shared

45
00:04:09,770 --> 00:04:14,330
Preference to store the current timing,
then I'd suggest doing that in the time

46
00:04:14,330 --> 00:04:19,370
Task function. That way the current
timing will be stored, at the same time

47
00:04:19,370 --> 00:04:25,310
as the row is added, or updated, in the
database. The bottom line is, don't rely

48
00:04:25,310 --> 00:04:31,250
on onCleared for saving state. Alright,
we were timing a task and the battery

49
00:04:31,250 --> 00:04:35,900
died. Let's pretend our user is no longer
travelling and connects their phone to a

50
00:04:35,900 --> 00:04:41,210
charger. They can now stop timing the
task. So let's see if that will work This

51
00:04:41,210 --> 00:04:46,280
is where you may get problems with the
emulator. We've tried this on fairly fast

52
00:04:46,280 --> 00:04:51,680
computers with plenty of RAM. If your
emulator runs slowly and is not very

53
00:04:51,680 --> 00:04:56,840
responsive, you may struggle with this
bit. I'll run the app again, and Android

54
00:04:56,840 --> 00:05:00,760
Studio will start the emulator again.

55
00:05:06,140 --> 00:05:11,990
Keep calm but work fast. When you see the
side menu appear, click the icon at the

56
00:05:11,990 --> 00:05:16,700
bottom again. Select battery on the left
and put the charger connection back to

57
00:05:16,700 --> 00:05:22,310
AC - that's over on the right hand side. If
you don't do that, the emulator will

58
00:05:22,310 --> 00:05:27,980
start up, see that it's battery has no
charge and shut down again. Also, drag the

59
00:05:27,980 --> 00:05:33,650
slider to give the battery some charge.
The emulator might shut down again, if

60
00:05:33,650 --> 00:05:38,270
you don't manage to connect the charger
before the battery's level is checked.

61
00:05:38,270 --> 00:05:44,380
If that happens, run the app again to start
up the emulator and repeat those steps.

62
00:05:47,830 --> 00:05:53,150
If that fails, you'll have to delete the
emulator and create a new one. In our

63
00:05:53,150 --> 00:05:56,810
testing, we haven't had any problems
restarting an emulator with a dead

64
00:05:56,810 --> 00:06:00,500
battery, but as I said, we're running
fairly fast computers with lots of

65
00:06:00,500 --> 00:06:06,640
memory. As you can see, my emulator
started up again. Our code's worked

66
00:06:06,640 --> 00:06:12,500
and it's still timing the task. I can long-
tap the task again, to stop the timing.

67
00:06:12,500 --> 00:06:17,570
That's pretty cool. The emulator's let us
test battery conditions, and we can write

68
00:06:17,570 --> 00:06:21,980
our apps to handle things, like the
battery running out of juice. And that's

69
00:06:21,980 --> 00:06:26,120
the end of this section. In the next
section, we'll create the reports

70
00:06:26,120 --> 00:06:29,540
activity, to display the timing data that
we've stored.

71
00:06:29,540 --> 00:06:33,040
I'll look forward to seeing you then.

