1 00:00:04,120 --> 00:00:09,680 Welcome back again. In the last video, we completed the changes to the various 2 00:00:09,680 --> 00:00:15,679 database classes. They can now handle the new CurrentTimingView. We just need to 3 00:00:15,680 --> 00:00:21,080 use it, in the TaskTimerViewModel class. I'll write the function 4 00:00:21,080 --> 00:00:29,620 retrieveCurrentTiming, and add it near the end of the class, just before onCleared. 5 00:01:08,659 --> 00:01:14,409 It's quite common, when querying a base view, to want all the columns. 6 00:01:14,409 --> 00:01:20,180 You normally write the views to only contain the columns you'll use. The Content 7 00:01:20,180 --> 00:01:24,740 Provider's query function will automatically return all columns when we 8 00:01:24,740 --> 00:01:30,560 pass a null as the projection. If you created a projection, that's fine. 9 00:01:30,560 --> 00:01:37,740 It won't do any harm - it's just unnecessary. Okay, if the cursor contains any rows, 10 00:01:37,740 --> 00:01:43,039 then we've got a timing record to retrieve. It should contain zero or one 11 00:01:43,039 --> 00:01:48,890 row, but we've written it to cope if more than one row's returned. The row we want 12 00:01:48,890 --> 00:01:55,100 will be the first one, because we sorted the data onStartTime in reverse order. 13 00:01:55,100 --> 00:01:59,420 The next bit of code is straightforward. We just get the data from the columns, 14 00:01:59,420 --> 00:02:04,630 in the cursor, and create a new timing instance. 15 00:02:41,300 --> 00:02:46,220 Android Studio is giving us a warning that we should close the cursor. 16 00:02:46,220 --> 00:02:50,720 It didn't always do that, and it may stop doing it in the future, so don't rely on 17 00:02:50,720 --> 00:02:55,850 these warnings. Get in the habit of closing resources like cursors, when you 18 00:02:55,850 --> 00:03:02,200 finish processing them. We also need to return the timing object that we've created. 19 00:03:13,340 --> 00:03:18,000 We're almost done, but there's something missing. The reason we created the 20 00:03:18,000 --> 00:03:23,400 CurrentTimingView, is so that we'd have a task name to display. There's no point 21 00:03:23,400 --> 00:03:28,170 going to all that trouble, if we don't display it, so let's do that. All we have 22 00:03:28,170 --> 00:03:34,100 to do is update the taskTiming's Live Data object. MainActivity's observing it 23 00:03:34,100 --> 00:03:37,680 and we'll update the display when it changes. 24 00:03:45,240 --> 00:03:48,820 Alright, that's our retrieveTiming function finished. 25 00:03:48,820 --> 00:03:52,120 It returns null if there's no record waiting to be timed, 26 00:03:52,120 --> 00:03:57,920 otherwise, it returns a timing instance with the correct task ID and start time 27 00:03:57,920 --> 00:04:02,960 When our ViewModel is created, it should use this function to retrieve any timing 28 00:04:02,960 --> 00:04:08,540 that's still waiting to be timed. We can use this function to do that, in the init block. 29 00:04:08,540 --> 00:04:19,500 I'll put it before the call to load tasks and then explain why. 30 00:04:19,500 --> 00:04:25,700 Alright, why is it important to call retrieveTiming before loading the tasks? 31 00:04:25,700 --> 00:04:31,180 If we load the tasks first, it's just possible that the user could long-tap one, 32 00:04:31,180 --> 00:04:36,260 to start timing it. If they do that, we might not stop timing the task we're 33 00:04:36,270 --> 00:04:41,220 trying to retrieve, because current task will still be null. By retrieving any 34 00:04:41,220 --> 00:04:46,530 outstanding timing first, we can be sure that won't happen. That's also why we're 35 00:04:46,530 --> 00:04:51,780 accessing the database on the main UI thread in retrieveTiming. We want the UI 36 00:04:51,780 --> 00:04:56,490 to block there, to make sure everything's loaded before the user can interact with 37 00:04:56,490 --> 00:05:00,120 the list of tasks. Remember, we're retrieving a single 38 00:05:00,120 --> 00:05:05,010 record from the local database, and that shouldn't be a long-running task. We can 39 00:05:05,010 --> 00:05:10,460 check how long it takes to execute, in logcat. Let's test the app to do that. 40 00:05:10,460 --> 00:05:16,700 I'll make sure the logcat's visible. Make sure you use the green run triangle here - 41 00:05:16,700 --> 00:05:26,440 don't use instant run. We want to make sure that the app is closed, and executed again. 42 00:05:26,440 --> 00:05:31,640 If we had a timing record saved, the app will show that it's still being timed. 43 00:05:31,640 --> 00:05:35,880 If we hadn't, it'll say No task being timed. 44 00:05:35,880 --> 00:05:41,860 I'll relaunch the app in a moment and we'll run this test again. In the logcat, 45 00:05:41,860 --> 00:05:51,780 we can see the retrieveTiming function starting. Don't forget that we can search 46 00:05:51,780 --> 00:05:55,710 for the TaskTimerViewModel, to cut down the number of lines that we're 47 00:05:55,710 --> 00:06:01,420 looking at. As you can see, the times for the start and the returning are the same, 48 00:06:01,420 --> 00:06:07,140 meaning that the time taken is less than one millisecond, and a view had to be 49 00:06:07,140 --> 00:06:13,520 created in that time as well. So the time executing the query is very, very short. 50 00:06:13,520 --> 00:06:18,030 Your times may be different, however, especially if your emulator is running 51 00:06:18,030 --> 00:06:24,680 slower than mine is. I'll start timing another task and then run the app again. 52 00:06:30,040 --> 00:06:36,050 This time, once again, the total time is zero. That's definitely going to be 53 00:06:36,050 --> 00:06:41,000 acceptable, but remember, this is running on a large computer, rather than on a 54 00:06:41,000 --> 00:06:45,500 handheld device. In the next video, we'll see how the app behaves when the user's 55 00:06:45,500 --> 00:06:50,020 battery runs out of charge. See you then.