Welcome back. When I open my AppProvider class,
I've got a load of errors.
If you don't see any errors, choose the rebuild project option from the
build menu and make sure the project builds successfully.
As you can see mine won't. You may not get as many
or you may have no errors.
If you created the class with later versions of the libraries,
your overridden functions will probably have the correct signatures.
I generated my overrides with old versions of the libraries
and the code is no longer correct.
That's mainly because Google have annotated the java methods
to make them more Kotlin friendly. As a result,
the function signatures no longer match the functions
that are being overwritten.
It all looks very scary because there are loads of errors,
but they're quite easy to fix.
This is why i start with the build files.
Changing library versions can sometimes cause problems
and it's much better to get them when we're about to review all the code.
It saves going through the code twice.
On line 35,
the error is that app provider doesn't override
the insert function.
It clearly does. We can see it on on line 131.
But the signature no longer matches the signature
in the API 29 ContentProvider class.
Of course, if you generated your function more recently than me,
you may not have these errors.
But it's useful to see the sorts of problems you can get
when changing your android version
or the versions of some libraries.
The easiest way to fix this is just to generate the stub again.
On the line above the insert function,
use ctrl O
and generate the insert function stub.
Notice that the values parameter is showing as a nullable
content values type.
The return value is a nullable type URI question mark (URI?)
make the parameter and the return value nullable
on line 135.
Then delete the stub that we just generated.
That's removed the error for this function.
We've got other errors inside the function, but let's fix update first.
Once again, that's a mismatched nullable parameter.
Add a question mark after content values
on line 173,
and that fixes it.
All the other errors are because context might be null.
Google added an annotation to the GetContext
method and Kotlin's now objecting
because the return value is now a nullable type.
You can see the @Nullable annotation
if you control click on context
on line 124. That's command click on a mac.
Notice in the docs string above the GetContext method
that it's only available after OnCreate has been called.
After that which is when we're using it, it shouldn't be null.
Back in AppProvider, we have to decide what to do about it.
We could use the bang bang operator.
But I prefer to avoid that whenever possible.
What I'll do instead is throw my own exception if context is null.
Using the bang bang operator will do the same thing
but I can include a more useful error message.
We use the Elvis operator and throw an exception if the Java
GetContext method returns null.
If it isn't null, which it won't be,
the local context variable fixes the problem we had
on line 125.
We've got the same problem in insert.
Because the context is used twice here,
I'll perform a similar check using the Elvis operator
near the start of the function.
I'm going to copy that to the clipboard.
Because we've ensured that the local context variable can't be null,
we no longer need to use a safe call.
That's down on line 170.
We've got the same problem four times in the update function
and the same solution works here.
Remember, I copied it to the clipboard.
Once again, we no longer need the safe call
on line 230.
And finally, the delete function.
Don't forget to remove the safe call down here.
That's all the errors fixed.
It can be scary getting a load of errors when changing the version of a library,
but as we saw they were usually easy to fix.
Most of ours had the same cause.
Annotations added to the Java framework that broke our Kotlin code.
Note that they wouldn't have caused a problem in a compiled app.
We'd already established that the context can't be null when we use it.
If we deployed our app to an API 29 device,
it would still work
even if we'd use framework code that had been annotated.
The annotations don't change the behavior of compiled code,
they just stop our code from compiling in the future.
Okay. I'll finish with the suggestions that we've got.
The first is a redundant semicolon on line
52.
I've no idea how that got there, it's not doing any harm
and you may find that programmers sometimes type one just out of habit
but I'll delete it anyway.
That leaves one more suggestion.
Variable declaration could be inlined
on line 66.
Use the light bulb to accept that suggestion.
We're now using when as an expression which is more idiomatic Kotlin.
We're almost done.
We've just got to do it to do
on line 125.
You can remove it now if you don't think you're going to need it for debugging.
I'll leave it in just in case something goes wrong
with some other changes that I'm going to make.
Review all your to-do's using the to-do tab at the bottom of the screen.
Always do that before releasing an app.
I'll finish the video with a small change to the AppDatabase class.
At the bottom of the file, we've got some commented out code.
That's from when we were looking at a companion object
before we use the SingletonHolder class.
We left it in for reference but it can be deleted now.
In the next video, we'll work on four other classes:
Cursor, RecyclerViewAdapter,
DurationsReport and the TwoViewModels. I'll see you over there.