G'day everyone, welcome back.
In the last video, we saw our AppDialog class displaying a dialog, when we try to delete a Task record.
The next step is to get MainActivityFragment to handle the situation correctly.
Correctly here means, not performing the deletion until the user has confirmed that they really do want to delete the task.
We achieve that by moving the deleteTask call into the onPositiveDialogResult function.
So we'll cut these two lines from here,
and paste them down here.
We've got an error because the task id isn't available.
We can fix that by retrieving the id from the args bundle.
We should also make sure that we're responding to the correct dialog.
We're only showing one dialog at the moment, but we don't want to go deleting tasks by mistake.
So let's wrap this in an if block.
I haven't included a check that the task id key exists in the bundle.
You could do, and throw an exception if it doesn't exist.
Let's check the documentation for the getLong function, using ctrl Q, or ctrl J on a Mac.
getLong returns 0 if the key isn't present in the bundle.
If that happens, it's a programming error.
It can't happen once the app's released, because Sqlite doesn't create integer primary key values of 0.
We should always have a non zero ID, unless the programmer has done something wrong.
Rather than throwing an exceptionm we can use an assertion.
This is different to just testing the task id and throwing an exception.
BuildConfig.DEBUG is a system-wide constant that the compiler can use.
When you produce the release version of the app, BuildConfi.debug will be false,
and this code won't be compiled into the final app.
It will only be present while we're developing, and won't appear in the released app.
This is one time where it's acceptable to put all the code on one line, by the way.
To see it working, I'll comment out the line that adds a task id to the bundle in the onDelete click function,
then run the app again.
I'll tap the delete button.
When I tap the dialog's delete button to confirm the deletion,
we get an exception in the logcat:
task id is zero.
There's a subtle difference between this MainActivityFragment class, and the AppDialog class.
MainActivityFragment is part of this TaskTimer app and won't be used anywhere else.
AppDialog, on the other hand, has been designed to be a general-purpose dialog class,
that we can use in other apps.
We could still be using other apps in ten years time.
Other members of our team could be including it in their apps,
so that's why we've taken a different approach to invalid arguments in the two classes.
Our assert error in MainActivityFragment is there to warn us that we've forgotten to store the task in the bundle.
The assert error code will be removed when the release version of the app's compiled.
The exceptions in AppDialog are intended to warn other programmers who use the class.
That may be us, but it may not be.
The AppDialog exceptions aren't removed when the code is compiled as a release version.
We might want to compile it, and include it in a library that's imported into other projects, for example.
So we want the checks to remain in the compiled release version.
Okay, I'll put back the code to store the id in the bundle,
and let's see if it works.
Run the app again, and I'm going to do the non-destructive tests first.
You don't want to spend time watching me type in the task records, so I'll try to keep deletions to a minimum.
I suggest you don't take that approach in your testing.
It makes sense when doing a quick check,
but always performing operations in the same sequence, can result in you missing bugs.
To make up an example, if your edit code creates a global object that's also used when you delete,
and you always edit before deleting. you might fail to spot that the delete code fails to create the object.
Okay.
I'll tap on the delete button to get the confirmation dialogue.
First, I'll use the cancel button.
Remember, that's not the same as cancelling the dialogue.
We give the button the caption cancel, but it's really the negative dialog button.
That's good. The record isn't deleted.
There are two ways to cancel dialogue, and both do exactly the same thing.
To test that, I'll delete again, and tap the screen outside the dialogue.
The dialogue closes, and the task hasn't been deleted.
The same thing should happen with the back button.
So get the dialogue back, and press the back button.
That's working fine as well.
Now to test deletion.
I'll clear the logcat, then delete a task and confirm the deletion.
A bit more happens here, because we're causing the database notification system to kick in.
But we can see the onPositiveDialogResult function, then the record being deleted,
and we can see it's gone from the emulator screen.
Mixed in with all the database logging, we can see the dialog's onDismiss and onDetach functions in the log.
Notice that the deletion and subsequent re-query, are happening on a different thread.
Alright, our AppDialog class is looking good.
There's a few things we haven't tested.
Does it work when we provide a different caption for the negative button?
Does it work when we don't provide any button captions, and rely on the defaults for both?
Does everything work okay in landscape.
I'm not going to go through those tests on the video,
but you should certainly test all combinations of input, to any classes you create.
I'll leave you to perform those tests, and stop this video here.
In the next video, we'll have a quick look at some strange behavior.
See you in the next one.