(bright music)
(typing)
OK, so we've seen the fragment lifecycle diagrams.
In this video, we're gonna log the functions being called
and see how it all plays out in action.
You could get Android to generate
all the stubs for you and then add logging to each one,
just like you did when we discussed the activity lifecycle,
but I'm sure you don't want to watch me
doing that all on video.
So, what I'm going to do is paste in the functions
at the end of Main Activity Fragment.
But firstly, I'm gonna open Main Activity Fragment.
(clicking)
We need to have the usual log tag, so we'll do that first.
(typing)
Private const val TAG equals MainActivityFragment.
Let's also add some logging in the onCreateView function
because we've already written that.
Log dot d parentheses TAG comma,
and it's going to be onCreateView called.
So, I've come down to the...
Just prior to the last right curly brace
and I'm gonna paste in these functions.
Paste them into that.
And just the various lifecycles functions overridden
just with a simple log, you can see there.
I've still got that code in my clipboard,
so I'm going to open AddEditFragment.
I'm gonna paste it in there just to save a bit of time.
Go right down to the bottom there
just prior to the last right curly brace.
Paste it in there.
And, what I'll do firstly is delete this code
that we commented out previously,
but also the fragment has already overridden
some of these functions that I've just pasted in,
so I'm gonna delete the duplicates,
and obviously I'll delete the duplicate that I've just added
and not the original code that we've changed.
So the first one was undetached there that I've just removed
from what was pasted in.
This is onActivityCreated that was also used
but we've also overridden that already
and these last two: onAttach and onCreate,
let's remove those as well.
Because again, we created or overrode
those functions in our code.
Alright so now we're logging all the
lifecycle events in both fragments.
We wanna see how these fit into the activity lifecycle,
so what I'm going to do is paste in
the appropriate activity functions,
lifecycle functions into main activity
before the final right curly brace.
So, I'm gonna open MainActivity
and to the bottom before the last right curly brace,
paste that in there and there's our logging functions
for the various lifecycle functions.
And by the way, you can download the code
to paste this from the resources section of this video.
We've got a text file: FragmentLifecycleCorebacks.txt.
which contains the functions for the fragments
and for our main activity.
Alright so if you remember from the slides,
the activities onCreate function may still be executing
while the fragment callbacks get called.
So, to make that clear in our log I'm gonna add logging
to the end of onCreate.
This is for our MainActivity.
I'm gonna add some logging down here
to that affect so we know.
Log dot d parentheses TAG comma onCreate finished,
and I thought I might add logging for this at the start
but obviously I haven't done that for some reason
so I'm gonna take the opportunity to add some logging
to the onCreate for MainActivity.
And the other thing I'm gonna do,
I'm gonna type inside of log in Twopane
so we know what the value of that is,
because that will prove useful
when we're testing this out.
So log dot d parentheses tag comma,
and we're just gonna put oncreate colon twopane is
dollar m twopane, just the value
of what twopane is set to.
Alright so we can now run the app,
and see these lifecycle events in the logcat.
So what we're gonna do is open
the logcat first, and I'm going to make
sure my emulator is already in landscape mode
which it is now.
So let's actually run this in landscape,
and see the lifecycle events in the logcat.
Can't go back to logcat, I need to
edit out the previous filter.
So I'm gonna remove that, we got
all our code, our logcat entries back.
I'm gonna filter my main activity.
To see any of the entries for the activity
and the fragment main activity.
And as you can see there that seems
to be behaving as we would expect it to do.
So firstly the oncreate function,
activities oncreate gets called,
followed by the fragment events onattach,
oncreate, oncreateview and on viewcreated.
And note that while that was happening
the oncreate was still running
the activities oncreate, then they
can see that there's the twopane debug option there,
that the output there that says twopane is true,
and then we've got oncreate,
I put it on oncreate which should be on oncreate,
we'll fix that shortly.
It's showing that that's been finished.
Then moving on down we've got onstart,
the activity is onstart getting called next.
And the activity is now created and started.
Now that the activity started the fragment
is now as you can see further on,
the fragment onactivity created and onviewstate
was stored, is also called.
Finally the act3v fragment starts and both
objects get an onresume call.
So I'm going to first thing head back
and fix up that top row oncreate that
should not be oncreated.
But then I wanna go back to the logcat.
What I'm gonna do is just put an entry down there, rotating.
(typing)
Then let's go back and rotate this
back into portrait mode now.
And back to our log to check that out.
So as we expected there, the activity is
destroyed and recreated.
Both the activity and the fragment
get on pause, followed in this case by onsaveinstancestate.
Now remember that it isn't guaranteed is called
onsaveinstancestate.
It's not a guarantee to happen before onstop.
It has here but it may or can be called
any time before ondestroy.
Now the remaining events happen
as we've discussed with both the
activity and the fragment being stopped and destroyed.
The teardown finishes when our fragment gets ondetach.
Because Android destroyed the activity,
we get it recreated again.
The events for the activity on the fragment
are the same as when the activity was created initially.
There are two differences here though.
Firstly, twopane is now set to false in our
oncreate method, because we're now in portrait.
Secondly, note that the onrestoreinstancestate
for main activity was called.
Remembe that fragments don't have that function,
you have to use one of the other callbacks
to restorestate, remembering to check for nobundle.
Alright so let's now see what happens when
we switch away from the activities,
I'm going to come down to the end of
the log and put home there.
Go back to our app.
I'm gonna tap the emulator's home button.
Now that's usually the middle button
and it is in this case here.
And sometimes have physical button
in place of the on-screen icon.
We're gonna click on that button now,
and going back to our log.
We can see both the, main activity
and main activity fragment.
So the activity and the fragment are both paused,
But then stopped.
Stop the onstop called as you can see
down in the bottom there.
We also get an onsaveinstancestate
called there as you can see.
As we'll see there is no need restorestate
if the user returns to and activity.
The activity is stopped however, it hasn't been destroyed.
So before returning to the app,
I'm going to add comment returning in the logcat.
(typing)
And now going back to emulator, we wanna use this
square multitasking button over here to the right.
And choose task timer from the list again,
and this the (??) that's currently running, click on that.
And you can see our logcat entry got updated.
Basically the activity and fragment
here restarted and resumed.
There's no callnote to onrestoreinstancestate
for the activity because the activity
was only stopped, it wasn't destroyed,
so therefore no state was lost.
So the final test now, I'm just
going to type back in here, the logcat.
The final test now is to go back to our app.
And use the back button to close the app,
that's this button down here.
We're going back to our log, our logcat again.
We got the onpause, the onstop but this time
also ondestroy being called, finishing with
fragments ondetach down the bottom there.
Note that onsaveinstancestate doesn't get called.
The user, me chose to quit the app, so android
won't attempt to restorestate if the app restarted.
Alright so that's the lifecycle for fragment that's
included in the activities layout.
As we'll see now it's almost exactly the same
when we add a fragment in our code.
So the logcat is gonna be a bit messy if
we leave the entries for main activity fragments showing.
And it's possible to exclude tags
from appearing in the log.
It's not obvious and this is a
good opportunity to show how to do it.
So first here I'm gonna choose the
filter to main activity, then add a pipe, add editfragment.
So the vertical bar, or pipe symbol
between the two tags means (??).
So this will filter ontags, onentries, rather.
Tagged with either mainactivity or add editfragment.
As we've seen the tag mainactivity
we'll also match mainactivityfragment as well.
So at the moment we're in portrait,
so we need to restart our app now to get that running again
so let's do that.
So we did stop it.
Now we're going to tap on the plus icon on the toolbar
to start the addeditfragment, and then we're gonna
look at how to tidy up the logcat.
Okay so the logcat is showing entries for
the activity at the moment.
That's got us both fragments.
As I said that's gonna get bit hard to read
when we rotate the device.
We wanna focus on the activity and addeditfragment,
and should exclude mainactivityfragment from appearing.
So to do that we need to click on any entry
in the log for mainactivityfragment to select it.
So I'm gonna just gonna double click this one here.
With the tag selected right click
and choose the option to fold line like this.
You can see that the dialogue appeared here
containing a list of strings that the logcat
will quote on quote fold, which means not to splay.
Mainactivityfragments been added to the
end of the list as you can see there.
Before I click okay notice the minus button,
we'll use that in minute to unfold these lines.
And that will be read on Linux and Windows
but as you can see it's grey on my mac.
So I'm gonna click okay here.
And notice what's happened, the mainactivityfragment
entry is no longer up here.
So that's a lot clearer now so
let's look at what's happened here.
So I wanna tap the plus icon, the taskedit request function
created a new instance of addeditfragment.
And you can see the taskeditrequest
starting there in the log.
And you can see after that point where the new
instance of editfragment was created, you can see it's
lifecycle functions being called, exactly
the same functions that were called
from mainactivityfragment earlier.
Our fragment goes through the same lifecycle
even when we create it in code.
What you might find surprising though, is that
onactivitycreated is called even though the
activity already existed, that's an important event,
because it let's the fragment know
that it's activity is started.
Android calls this function to let the fragment know that.
So don't think of it as happening
when the activity is created, think of it
as Android letting the fragment know
that it's activity is started.
When you attach a fragment, it'll get this callback
whether you've attached it in the
layout or attached it in code.
Alright so I'm gonna add the comment
rotating here in the logcat.
Then let's go ahead and rotate the device into landscape.
If you come down here, if you take a look at the entry
showing on the screen here we got exactly the same
sequence as we got from mainactivityfragment.
Our fragment was attached to the activity
and there's now no difference between a fragment attached
in code and one attached via the layout.
The activity goes through it's destroy
and recreate lifecycle events and
then the attached fragment follows that.
The last thing to check then is what happens
when we remove the fragment in code.
So I'm gonna add the comment to
the logcat, removing (typing).
Then I'm gonna go back to the app and
I'm gonna click on save, which will
remove the addeditfragment.
And back to the logcat, although we could see it.
And you can see down there with the log entry
towards the bottom.
Obviously we've got our onsaveclicked called,
removeeditpane, then the fragment goes through the
destroy phase of it's lifecycle onpause, onstop
ondestroyview, then ondestroy and ondetach.
So that's the fragment lifecylcle.
We've seen that a fragment can go through it's
lifecycle independently of the activity it's attached to
if the fragment was attached in code.
Even so the fragments lifecycle is tied to that
of it's activity as we saw when
we rotated the device just now.
We'll be adding dialogues to the app
a bit later in the cause, and you'll see that the dialogue
fragment has the same lifecycle as an ordinary fragment.
For now though that's enough on the lifecycle.
Before I stop this video we better see how
to get those log entries to appear again.
So the quick way if you just want to see a single entry,
is to use the plus button at the start of some of the lines.
So you can tell that a line has been folded,
because you'll have the lines that look like this
on the right hand side here with N interncall
where N is a number one or higher.
So I can come over here and just click
on the plus to the left of these lines.
Now that unexpanded the lines or brings them back
so you can actually see them again.
So to complete removing the folding,
select something by right clicking again,
so I'm just going to select the mainactivityfragment again,
right click, and click on fold lines like this again.
So to completely remove the unfolding,
select something and right click it again as you saw me do.
It doesn't matter what you select, although I prefer
to select the same tag that I folded.
Alright so now we got the same entry, mainactivityfragment
appearing twice now in the dialogue, if you selected some
other text you'll see that instead of one of these entries.
So select each one in turn, and use the minus button to
delete it from the list, so I gotta do that twice.
We've now removed that from the list of entries to fold.
Click on okay and you can see that they're all now
appearing again as I would have normally done.
Alright so that's the folding now being removed, and
we've got our full list of entries
that match our filtered text.
Let's end the video here now and in the next one we're gonna
add support for the back and up buttons to allow the users
to return to the main activity.
So I'll see you in the next video.