1
00:00:05,200 --> 00:00:08,860
Welcome back. When I open my AppProvider class,

2
00:00:09,530 --> 00:00:11,130
I've got a load of errors.

3
00:00:12,930 --> 00:00:16,930
If you don't see any errors, choose the rebuild project option from the

4
00:00:16,930 --> 00:00:20,830
build menu and make sure the project builds successfully.

5
00:00:21,430 --> 00:00:25,090
As you can see mine won't. You may not get as many

6
00:00:25,090 --> 00:00:26,590
or you may have no errors.

7
00:00:27,140 --> 00:00:30,640
If you created the class with later versions of the libraries,

8
00:00:30,640 --> 00:00:34,440
your overridden functions will probably have the correct signatures.

9
00:00:34,940 --> 00:00:37,940
I generated my overrides with old versions of the libraries

10
00:00:38,540 --> 00:00:40,140
and the code is no longer correct.

11
00:00:40,640 --> 00:00:44,340
That's mainly because Google have annotated the java methods

12
00:00:44,340 --> 00:00:47,340
to make them more Kotlin friendly. As a result,

13
00:00:47,700 --> 00:00:50,900
the function signatures no longer match the functions

14
00:00:50,900 --> 00:00:52,200
that are being overwritten.

15
00:00:53,000 --> 00:00:55,800
It all looks very scary because there are loads of errors,

16
00:00:56,300 --> 00:00:57,800
but they're quite easy to fix.

17
00:00:58,800 --> 00:01:01,400
This is why i start with the build files.

18
00:01:01,800 --> 00:01:04,800
Changing library versions can sometimes cause problems

19
00:01:05,300 --> 00:01:08,800
and it's much better to get them when we're about to review all the code.

20
00:01:09,200 --> 00:01:11,100
It saves going through the code twice.

21
00:01:11,400 --> 00:01:13,500
On line 35,

22
00:01:13,500 --> 00:01:16,860
the error is that app provider doesn't override

23
00:01:16,860 --> 00:01:18,260
the insert function.

24
00:01:20,260 --> 00:01:24,260
It clearly does. We can see it on on line 131.

25
00:01:27,460 --> 00:01:30,460
But the signature no longer matches the signature

26
00:01:30,460 --> 00:01:33,660
in the API 29 ContentProvider class.

27
00:01:34,060 --> 00:01:37,960
Of course, if you generated your function more recently than me,

28
00:01:37,960 --> 00:01:39,460
you may not have these errors.

29
00:01:39,960 --> 00:01:42,960
But it's useful to see the sorts of problems you can get

30
00:01:42,960 --> 00:01:44,960
when changing your android version

31
00:01:45,210 --> 00:01:47,210
or the versions of some libraries.

32
00:01:47,460 --> 00:01:51,450
The easiest way to fix this is just to generate the stub again.

33
00:01:52,110 --> 00:01:54,310
On the line above the insert function,

34
00:01:55,560 --> 00:01:57,060
use ctrl O

35
00:01:58,050 --> 00:02:01,050
and generate the insert function stub.

36
00:02:06,300 --> 00:02:10,600
Notice that the values parameter is showing as a nullable

37
00:02:10,600 --> 00:02:12,100
content values type.

38
00:02:12,700 --> 00:02:16,800
The return value is a nullable type URI question mark (URI?)

39
00:02:17,100 --> 00:02:20,600
make the parameter and the return value nullable

40
00:02:20,600 --> 00:02:22,600
on line 135.

41
00:02:29,260 --> 00:02:31,610
Then delete the stub that we just generated.

42
00:02:35,610 --> 00:02:37,610
That's removed the error for this function.

43
00:02:38,410 --> 00:02:43,010
We've got other errors inside the function, but let's fix update first.

44
00:02:43,010 --> 00:02:46,410
Once again, that's a mismatched nullable parameter.

45
00:02:48,710 --> 00:02:51,710
Add a question mark after content values

46
00:02:52,070 --> 00:02:53,970
on line 173,

47
00:02:54,960 --> 00:02:55,960
and that fixes it.

48
00:02:56,760 --> 00:03:00,560
All the other errors are because context might be null.

49
00:03:00,860 --> 00:03:04,160
Google added an annotation to the GetContext

50
00:03:04,660 --> 00:03:06,460
method and Kotlin's now objecting

51
00:03:06,460 --> 00:03:09,460
because the return value is now a nullable type.

52
00:03:11,460 --> 00:03:14,060
You can see the @Nullable annotation

53
00:03:14,420 --> 00:03:17,220
if you control click on context

54
00:03:17,220 --> 00:03:20,820
on line 124. That's command click on a mac.

55
00:03:25,020 --> 00:03:28,820
Notice in the docs string above the GetContext method

56
00:03:28,820 --> 00:03:32,920
that it's only available after OnCreate has been called.

57
00:03:33,280 --> 00:03:36,880
After that which is when we're using it, it shouldn't be null.

58
00:03:37,580 --> 00:03:41,080
Back in AppProvider, we have to decide what to do about it.

59
00:03:41,940 --> 00:03:44,640
We could use the bang bang operator.

60
00:03:45,000 --> 00:03:47,200
But I prefer to avoid that whenever possible.

61
00:03:48,070 --> 00:03:52,670
What I'll do instead is throw my own exception if context is null.

62
00:03:53,170 --> 00:03:56,050
Using the bang bang operator will do the same thing

63
00:03:56,050 --> 00:03:58,250
but I can include a more useful error message.

64
00:04:34,650 --> 00:04:39,050
We use the Elvis operator and throw an exception if the Java

65
00:04:39,050 --> 00:04:41,150
GetContext method returns null.

66
00:04:41,650 --> 00:04:44,250
If it isn't null, which it won't be,

67
00:04:44,500 --> 00:04:47,700
the local context variable fixes the problem we had

68
00:04:47,700 --> 00:04:49,300
on line 125.

69
00:04:49,960 --> 00:04:52,560
We've got the same problem in insert.

70
00:04:56,220 --> 00:04:59,420
Because the context is used twice here,

71
00:04:59,420 --> 00:05:03,020
I'll perform a similar check using the Elvis operator

72
00:05:03,220 --> 00:05:04,920
near the start of the function.

73
00:05:40,580 --> 00:05:42,380
I'm going to copy that to the clipboard.

74
00:05:43,040 --> 00:05:46,700
Because we've ensured that the local context variable can't be null,

75
00:05:47,100 --> 00:05:49,300
we no longer need to use a safe call.

76
00:05:51,900 --> 00:05:53,900
That's down on line 170.

77
00:05:59,900 --> 00:06:03,400
We've got the same problem four times in the update function

78
00:06:03,900 --> 00:06:05,560
and the same solution works here.

79
00:06:12,060 --> 00:06:14,360
Remember, I copied it to the clipboard.

80
00:06:14,860 --> 00:06:18,160
Once again, we no longer need the safe call

81
00:06:20,160 --> 00:06:21,960
on line 230.

82
00:06:23,620 --> 00:06:26,220
And finally, the delete function.

83
00:06:42,420 --> 00:06:45,020
Don't forget to remove the safe call down here.

84
00:06:45,520 --> 00:06:47,120
That's all the errors fixed.

85
00:06:47,780 --> 00:06:52,140
It can be scary getting a load of errors when changing the version of a library,

86
00:06:52,440 --> 00:06:55,040
but as we saw they were usually easy to fix.

87
00:06:55,540 --> 00:06:57,340
Most of ours had the same cause.

88
00:06:57,700 --> 00:07:01,800
Annotations added to the Java framework that broke our Kotlin code.

89
00:07:02,600 --> 00:07:06,100
Note that they wouldn't have caused a problem in a compiled app.

90
00:07:06,700 --> 00:07:10,000
We'd already established that the context can't be null when we use it.

91
00:07:10,700 --> 00:07:13,700
If we deployed our app to an API 29 device,

92
00:07:13,700 --> 00:07:14,900
it would still work

93
00:07:15,300 --> 00:07:18,300
even if we'd use framework code that had been annotated.

94
00:07:19,100 --> 00:07:22,460
The annotations don't change the behavior of compiled code,

95
00:07:22,860 --> 00:07:25,460
they just stop our code from compiling in the future.

96
00:07:26,560 --> 00:07:29,560
Okay. I'll finish with the suggestions that we've got.

97
00:07:29,960 --> 00:07:33,560
The first is a redundant semicolon on line

98
00:07:35,060 --> 00:07:35,960
52.

99
00:07:37,360 --> 00:07:40,860
I've no idea how that got there, it's not doing any harm

100
00:07:40,860 --> 00:07:45,060
and you may find that programmers sometimes type one just out of habit

101
00:07:45,310 --> 00:07:46,670
but I'll delete it anyway.

102
00:07:49,670 --> 00:07:51,770
That leaves one more suggestion.

103
00:07:52,470 --> 00:07:55,170
Variable declaration could be inlined

104
00:07:57,970 --> 00:07:59,470
on line 66.

105
00:08:00,370 --> 00:08:03,170
Use the light bulb to accept that suggestion.

106
00:08:05,970 --> 00:08:10,570
We're now using when as an expression which is more idiomatic Kotlin.

107
00:08:11,230 --> 00:08:12,430
We're almost done.

108
00:08:12,980 --> 00:08:14,640
We've just got to do it to do

109
00:08:16,440 --> 00:08:18,440
on line 125.

110
00:08:18,940 --> 00:08:23,040
You can remove it now if you don't think you're going to need it for debugging.

111
00:08:25,740 --> 00:08:28,140
I'll leave it in just in case something goes wrong

112
00:08:28,140 --> 00:08:30,340
with some other changes that I'm going to make.

113
00:08:30,700 --> 00:08:34,700
Review all your to-do's using the to-do tab at the bottom of the screen.

114
00:08:36,799 --> 00:08:39,000
Always do that before releasing an app.

115
00:08:39,990 --> 00:08:44,090
I'll finish the video with a small change to the AppDatabase class.

116
00:08:52,490 --> 00:08:56,190
At the bottom of the file, we've got some commented out code.

117
00:08:58,890 --> 00:09:01,890
That's from when we were looking at a companion object

118
00:09:01,890 --> 00:09:04,390
before we use the SingletonHolder class.

119
00:09:04,890 --> 00:09:08,090
We left it in for reference but it can be deleted now.

120
00:09:14,090 --> 00:09:17,750
In the next video, we'll work on four other classes:

121
00:09:18,250 --> 00:09:20,360
Cursor, RecyclerViewAdapter,

122
00:09:20,360 --> 00:09:24,760
DurationsReport and the TwoViewModels. I'll see you over there.

