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.