Keeping Track of Instance State6:09 with Ben Deitch
In this video we'll do some debugging and learn about how Fragments are saved and restored!
We've just discovered that when we rotate the app, 0:00 we end up with two list fragments. 0:03 And what's worse is that if we keep rotating the app, 0:05 we get another new list fragment on each rotation. 0:08 So why is this happening? 0:12 Well, it's actually just Android trying to be 0:13 helpful by restoring our fragments automatically. 0:16 When we launch the app, we create our list fragment and 0:19 we add it to our UI by using the fragment manager. 0:22 Then, when we rotate the app, our fragment is automatically restored and 0:25 we create a new fragment. 0:30 To see this a little better, let's do some debugging. 0:33 Let's add a break point to our activities super.onCreate method, 0:38 and then hit the Debug button. 0:45 After a few seconds, we should be stopped at our break point. 0:51 Nice. 0:56 Notice that we have a null savedInstanceState. 1:00 Now, since we're mostly interested in what happens after we rotate the app, 1:03 let's hit the resume program button and then rotate the app. 1:08 And now we're back at our breakpoint again except 1:17 this time savedInstanceState isn't null. 1:19 Let's step into this super.OnCreate method by using this button over here. 1:23 Then let's step over this first log call. 1:30 And then let's take a look at the log. 1:35 So far so good, just the one onCreate message. 1:42 Back on the debug tab, let's step over this super call as well 1:47 and once that's done, let's check the log again. 1:53 This is what I mean when I say that the fragment will be automatically restored. 1:57 We didn't do anything and yet here we have onAttach and onCreate for our fragment. 2:02 So going back to the debug tab, if we step out of this method 2:08 to go back to main activity it becomes pretty clear where the problem is. 2:13 We shouldn't be making a new list fragment if we already have one. 2:24 Okay, let's go ahead and end this debugging session and 2:30 see how we can fix this. 2:32 Remember that when we first launched the app, savedInstantState was null. 2:35 But when we rotated it, saveInstanceState got a value. 2:41 So really all we need to do is say if 2:45 savedInstanceState is null. 2:50 Then add our fragment. 2:59 Let's quickly run this. 3:03 And if we rotate the app it looks like it worked and it did work. 3:10 This is a perfectly acceptable solution to our problem. 3:18 But depending on your app, it might not be the best solution. 3:22 What if we needed access to our list fragment instance from another method and 3:26 main activity? 3:30 We could refactor our list fragment to be a field, but 3:32 still this field is only being set when savedInstanceState is null. 3:35 To fix this above the if statement 3:40 let's create a new list fragment variable named savedFragment. 3:45 And set it equal to getFragmentManager.findFrangmentById(R.id- 3:55 .placeholder). 4:02 Then let's use Alt Enter to cast the returned fragment as a ListFragment. 4:04 The findFragmentById method takes in a resource ID and returns a fragment. 4:13 If the fragment can't be found it returns null. 4:18 The resource ID we pass in should either be the ID of the fragment 4:22 if it was added directly to the XML or 4:26 the ID of the fragment's placeholder if it was added dynamically. 4:28 Now instead of checking if savedInstanceState is null we can instead 4:35 check if savedFragment is null. 4:39 Which for now makes the code a little bit easier to read. 4:44 We look for a ListFragment and if we don't find it, we create and add a new one. 4:49 Now, let's do one last test to make sure everything is in good working order. 4:57 So if I rotate and rotate and scroll a bunch. 5:06 Nice, no double fragments. 5:17 And if we look over to the log. 5:19 We've only got one fragment on resume call, just like it should be. 5:23 Now that we've got our life cycle under control, let's go ahead and 5:29 un-extend our logging classes. 5:32 Change logging activity back to AppCompatActivity, 5:34 and over in ListFragment change LoggingFragment 5:40 back to Fragment, and remove the log call. 5:44 Then I'm going to delete the two logging classes. 5:53 But you should feel free to keep them around. 5:57 In the next video we'll start work on launching a new fragment when we receive 6:03 a tap on our ListFragment. 6:07
You need to sign up for Treehouse in order to download course files.Sign up