[MUSIC] So let's take a deeper look at these lifecycle methods. The first method that gets called is OnCreate. OnCreate gets called when the activity is first created. Typically OnCreate is used to initialize the activity and will carry out the following four functions. It will call super.onCreate so Android can do some of its own initialization. It will set the activity's content view, which tells Android what the activity's user interface should be. Next, it will capture and retain any references it needs to the various views or elements of the user interface. And finally, it will configure the user interface views and elements as required. So, let's take a look at MapLocation's onCreate method. Here I've opened up the MapLocation application in Eclipse. And now, I'll open up the MapLocation activity. And here, as you can see, the MapLocation class is a subclass of Activity and it overrides Activity.onCreate. Inside the onCreate method, you see the four functions we just talked about. First, there's a call to super.onCreate. Next, there's a call to setContentView, passing in the ID of a layout file as a parameter. After that, the activity stores references to an EditText view and to a button which appear in the user interface. And finally, onCreate attaches a listener to the button. Android calls this listener code every time the user presses this button. So, this listener code is listening, for presses of the button. OnRestart is another lifecycle method. It gets called if the activity has been stopped, but is about to be started again. And you can use onRestart to handle any special processing that you need, that, or that is needed only after the activity's been stopped, but is about to start again. onStart is called when the activity is about to become visible. And some typical applications for this method include starting when visible-only behaviors, like requesting location sensor updates, or loading or resetting persistent application state, things like updating the unread messages queue for an email reader application. The onResume method gets called when the activity is visible and about to start interacting with the user. And some things you do in this method are to start foreground-only behaviors, things like starting animations or playing a background sound track. onPause is called when your activity is about to lose focus. In this method, you can shut down foreground-only behaviors, things like killing animations. And you should also save any persistent state that the user has edited. onStop is called when the activity is no longer visible to the user. At this point, it's possible that the activity may be restarted later. So, some typical things to do here include caching activity state that you'll want to restore when the activity is later restarting and onStart is called. And remember, onStop is not always called when an activity terminates. For instance, it may not be called if Android kills the application's process due to low memory. So don't wait to save persistent data in this method. Go do that back in onPause. onDestroy is called with the activity is about to be destroyed and some typical actions to do here include releasing activity resources. For example, shutting down private threads that were started by this activity. And again, remember, onDestroy may not be called at all. For example, when Android kills an application due to low memory on the device. So, returning back to MapLocation, you'll see that I've also overridden most of the activity lifecycle methods, including onStart, onRestart, onResume, onPause, onStop, and onDestroy. In each of these methods, you'll see that I placed a method call that logs some information about the method being called. And I encourage you to run the MapLocation application yourself and to watch the logcat view to see exactly what's being written. And I want you to try pressing different buttons like the Back button and the Home button, and different keys to verify for yourself that the lifecycle method calls are following the graphic depiction that we saw earlier. So now that we've seen the activity lifecycle in action, let's take a look at how one activity can programatically start another activity. To start an activity programatically, you first create an Intent object that specifies the activity that you want to start. And then you pass this newly created Intent to methods such as startActivity or startActivityForResult. startActivity will start up the desired activity, pushing the current activity out of the foreground. startActivityForResult will also start up the desired activity, but it will do so with the expectation that the started activity will provide a result back to that calling activity. And in this case, the result is communicated back by a call to that activity's onActivityResult method. And we'll come back to that in a few minutes. So, for now, let's go back into Eclipse and look at how MapLocation actually starts up the Google Maps activity. Here I'm showing where MapLocation has attached a listener to the Show Map button. Whenever the user clicks this button, the listener's onClick method will be called. And as you can see, that code creates an Intent and then pass Intent to the startActivity method. And the end result of this is that a Google Maps activity will open up, showing a map centered on the address that the user entered. Now, you remember that entering an address in MapLocation was pretty slow. Well, here I'm going to show you a different application that, instead of asking the user to enter an address through the keyboard, will allow him or her to select a contact from the Contacts application and allow him or her to use the address of that contact as the address to center the map on. Let's take a look at this application called MapLocationFromContacts. So here's my device running. I'll launch the MapLocationFromContacts application. And now you see a button that will allow me to select an address from an existing contact. When I click on that button, a new activity is started. Now, this activity is actually part of the Contacts application which will show me my contacts and allow me to select one of them. So here, I'll do that and I'll select my own name, Adam Porter. Now, the Contacts application has no idea what I want to do with this selected contact. In particular, it can't start or show the map itself based on this contact. It just wasn't designed to do that. So what I've actually got happening here is that MapLocationFromContacts has asked the Contacts application to return the data to it once the user selects the contact. And it does that by starting the Contacts application via a startActivityForResult, rather than by using startActivity. Now, once the contact is selected, MapLocationsFromContacts will then receive the selected data and it will call Google Maps to display that information. So let's see that in the code. Now here, I'm opening the MapLocationFromContacts application in Eclipse. And the structure of the main activity is pretty similar to what we saw in MapLocation, but you'll notice that the code in the button listener is a little bit different. In particular, this code creates a slightly different Intent and then passes that Intent as a parameter to startActivityForResult. We'll look at intents in more detail in the next lesson. But you can also see here that startActivityForResult takes a second parameter, which represents a request code. And this will come in handy later when the result is returned back to the started activity. Once the new activity is started, it is responsible for setting the result that should be returned back to the calling activity. And it does this by calling Activity.setResult, passing in a result code and optionally passing in some result data. Now, these result codes include some built-in code such as RESULT_CANCELED, which indicates that the user chose not to complete the activity normally. They probably hit the Back button, for example. And RESULT_OK, indicating that the activity, in fact, completed normally. Developers can also add custom result codes after the built-in result code, RESULT_FIRST_USER. Now, before the activity ends, the activity must set its result by calling setResult and this result will eventually be transmitted back to the calling activity via the call to onActivityResult. So let's take a look at that code in the MapLocationFromContacts application. Here's onActivityResult. As you can see, its parameters include the initial request code that was passed into startActivityForResult, the result code used by the started activity when it called setResult, and an Intent object if it was passed in when setResult was called. onActivityResult usually starts off by checking the result code and request codes to determine what to do with that particular result. In this example, the next steps are to retrieve the underlying contact data and to parse it to extract just the postal address of the contact. Now, the details aren't important now, so I'll skip over them. But once the postal address has been extracted, MapLocationFromContacts operates just like MapLocation did. It processes the data so that it's in a format that Google Map expects, puts that data into an Intent object, and then call startActivity, passing in that Intent. The last topic I'll discuss today is handling configuration changes. A device's configuration refers to device and application characteristics related to application resources, things like languages used, screen size, keyboard availability, and device orientation. Now, these characteristics can change at runtime. And when they do, Android will usually kill the current activity and then restart it with the appropriate resources for the changed configuration. Now, since configuration changes can happen frequently while using an application, you want to make sure that your lifecycle method code is fast. Consider device orientation changes, for example. If you move the device from portrait mode to landscape mode, and back to portrait mode, that will cause the current activity to be killed and restarted twice. So if your startup code is slow, that's really going to affect your users' experience with your application. So, to improve the speed of configuration changes if you need it, Android allows you to do two things. One, as the change is occurring, you can create and save an arbitrary Java object that essentially caches important state information. And two, you can manually handle the configuration change, avoiding the whole shutdown and restart sequence all together. Let's talk about each one of those one at a time. So to speed up reconfiguration, I said you can cached hard to recompute data and store it in a Java object. And one way to do this is by overriding the onRetainNonConfigurationInstance method, which will be called some time between onStop and onDestroy. And the object that you build and return in onRetainNonConfigurationInstance can be retrieved when the activity is recreated by calling getLastNonConfigurationInstance. And that's usually done during the call to the activity's onCreate method when you recreate the activity. Now, note that these methods have been deprecated in favor of other methods in the Fragment class. And we haven't discussed fragments yet, but we'll come back to it in a later lesson when we do. Now, the second thing you can do to speed up reconfiguration is to avoid the whole kill and restart sequence altogether for specific configuration changes. And to do this, you declare those specific changes that the, your activity will handle in the AndroidManifest.xml file. For example, this XML snippet indicates that MyActivity will manually handle changes in device orientation and screen size and keyboard accessibility. So, if you do handle some configuration changes manually, then when those configuration changes occur in runtime, your activity will receive a call to onConfigurationChanged. And as a parameter, this method will receive a Configuration object which details the new configuration, so your code can then read this object and make whatever changes it needs to.