 Hello, everyone, a little bit smaller up here today. Today's video, I'm going to introduce to you the Android Activity Lifecycle, which is a hugely important concept that you need to grasp in this course of developing Android applications. And mobile applications on iOS also follow kind of a similar lifecycle model. And we'll explain, I'll show you what that means. Probably it will illuminate some strangely named methods that you have seen in your activities kind of appearing. And then I'll also talk in a little bit of depth about the Android Runtime, or the ART, which is basically the operating system that is underlying how Android does stuff. And if we understand just a little bit more about how that thing works, it makes a little more sense why we have these so-called lifecycle methods. So, and one other comment I have just before we get started is, in the first half of this course, I'm very heavily relying on the book. So these lectures that I give, they're really introductory. Most of the learning takes place out of the book. In another week or four or so, four more topics, I think, once we get through the user interface stuff, we'll start getting into a lot more custom-generated content from me. So if you're feeling a little sort changed, like, oh, man, he's just giving me stuff out of the book. Well, I am just giving you stuff out of the book because I believe in the book. I think the book presents it very well. But soon enough, in a couple of weeks, once we've got all these user interface things under the belt, we'll switch over to some more stuff that you won't find in any book. But anyway, let me introduce to you this topic here today. All right. So the activity lifecycle. What we are talking about is when your activities start up and appear on the screen. So that's the beginning of the activity lifecycle. And it kind of corresponds in Java terms to whenever the class constructor for the activity is called, and it fires up on the screen. But in Android, if you're using this on a phone or in the simulator, other things happen unlike in regular applications where they're just kind of always running in the background or, I should say, they run to completion. They do some processing in the exit, like a regular Python program, regular Java program. These user interface-based programs, they're kind of sitting there and they're waiting for something to happen. And if you're in a shared environment, like a phone, the user might switch to other apps. Or if you're on your desktop in Windows and OS X, the user might switch to other apps. And that has impacts on your Android application as well. And you want to handle those transitions. I'll kind of talk a little bit about when they're important here. So I'm going to introduce these activity lifecycle things to you, and the book will go into them in much more detail in chapter four. Probably the easiest way to organize the thought of the Android activity lifecycle is through methods that are called. So if we look over here in this diagram, you have whenever the user starts your app, they hit the button from the launcher, the first thing that happens is the activity, the main activities on create method is called. And you have seen this. You have seen this method in your code. And what you want to do, it's different from the constructor, okay? This is, you can have code in your class constructor for the activity, but what on create is saying is, hey, the user is getting ready to start your app. So if you need to do things like read in data from a database or maybe restore some preferences or some history that the user had, now's the time, do this stuff before I get displayed on the screen, okay? This is your chance to do some processing before the activity is actually drawn on the screen. That's what on create does, okay? So again, what kind of stuff goes in here? It just depends, right? It just depends. You'll see some examples in your book. After on create, right? So you have this method in your activity called on create, right? It gets triggered at this point when the user has pressed the button and it's starting to come up. There's another method that you probably have not yet encountered called on start. Starting is the next step. Starting means the activity is going, is being shown on the screen now, okay? This thing is coming up. You see something there, okay? On start is the time to fill in your user interface, right? If you've like read some data from preferences or a database or you've got some history somehow and you wanna customize the widgets that are on the screen based on some data model, do it in on start. Now the UI is alive. In on create, in the creation part of the activity lifecycle, the UI's not there. It's firing up, it's getting ready. On start means your app comes on the screen and it's there, it's rendered, it's ready to go, okay? So the third one is on resume. On resume is a little tricky. We'll come back to it in a minute. It's better given in a context of its counterpart, okay? So know that when you start an activity, these three methods get called in sequence on your activity. Now other things are being called kind of behind the scenes by Android in between in each of these interstices here, right? Okay? But you don't need to worry about that, all right? You just say, all right, there's certain times like in on create, I need to maybe fire up my data, load my data, in on start, I need to change up what's shown on the screen to reflect whatever I've read. On resume, we'll get to in just a second. But these things run in relatively quick succession and then now your activity is running. It's on the screen, the user can interact with it. Okay, so these are like the startup phases. Now we're gonna do the steps of the life cycle that happen whenever the user goes away from your app, okay? So the first one is on pause, okay? Another activity comes into the foreground, all right? This can happen whenever, for example, you get a dialogue box that pops up over your app, not a notification at the top, but a dialogue box. It's like, do you accept these terms and conditions? That pauses your activity, okay? It could also be the case, you know, you can, some people have, you can just swap out, right, which app is on top. But maybe your activity is a stopwatch you want to keep running in the background. Things like that, okay? Pausing means that someone else, another activity has come into the foreground. What is the foreground? The foreground is the thing that's gonna intercept any button presses. So that basically means that, while the user may be able to see your app in the background, they can't interact with it. They can't click on any buttons. They can only interact on something else in the foreground. Okay? So you may want to have some stuff in here that like disables buttons, or, you know, I'm not sure necessarily. It just means that somebody else has come in front. Now, if the user comes back, okay? So the dialogue box popped up, your activity got paused. Maybe a good case will be like a game, right? You're playing a game and a pop-up box comes up. You probably want to pause the game, literally. Pause the game, right? So it's not going on there. That's a good thing to do and on pause. Now the user comes back to your activity. They dismiss that dialogue box that was in the foreground. What, that's when on resume is called, okay? Now we want to restart our game kind of automatically, right, that's when on resume is called. On resume is more useful. Don't think of it after on start. Think of it after on pause has exited, okay? All right, so this only happens though if the user comes back to your activity. On resume, you know, your activity could pause, but you know, maybe the user forgets about it, okay? If the activity goes away from the screen, okay? So this would be the case where you're sitting in your Canvas application and you switch over to Spotify or some YouTube completely. In that case, your activities on stop method is called. You stop the activity, okay? What this means is you need to stop updating the user interface. So again, imagine you're playing a game or imagine you're displaying a stop watch or you're showing a progress bar on a download or a progress bar on a music play, music playing track kind of thing. You want to stop those things from updating your widgets on the UI. You will get exceptions and errors if you do not, okay? Now your activity is not completely dead. It's just stopped, it's not on the screen. It's widgets aren't being redrawn and the reason Android does this is redrawing widgets is, well, it's pretty expensive. And if they're not being shown on the screen, then don't, Android's not gonna deal with that, right? Forget about it. So on stop gets called and that's just your signal, hey, user's gone away, something else is completely covering the screen. They can't see your activity just so you know, stop updating the user interface. Now a method may be called, all right? So you've swapped over to Spotify and now you're coming back to your app, on restart. On restart gets triggered just before on start and that's your signal that, hey, the user had previously switched away. They had called on stop and now they've come back. Time to start updating that UI again, okay? On restart gets called followed by on start, followed by on resume and then you're running again, okay? So all three of these will get called. The final one is on destroy, okay? On destroy is the opposite of on create and the operating system has, well, the user has closed the app so not just put it in the background but like swiped up or swiped down and it's gone. They killed it, they don't want it running anymore. Totally gone. You've got to release all of the resources that you're doing. You want to try and save all your data, things like that. Make sure everything's kosher. On destroy can also be called by Android itself, right? So if the user was using your app a little bit and then they put it in the background and it's been running for three days but they've not touched it, Android's probably going to kill your app. You don't have any control over that whatsoever. Android just says, you're not being used, see you later. It can take a while for that to happen and there's a lot of variables that decide how much memory are the other apps trying to use and can Android save some by killing yours or if your app has some pretty invasive permissions that it uses like recording the microphone or location, Android might kill your app if it's running back there as you don't need to be there. The problem with on destroy is you don't know when it's gonna be called. And it's not reliably called either. This is a problem endemic to any piece of software that you write with the halting problem, right? In theory of computation, software doesn't know when it's gonna be killed. It can't know, it can't ever know when it's going to die. So the best place that, but Android knows, the operating system knows, it's not guaranteed to call on destroyed. So usually it's a good idea where if your users entered some data or you have some statistics you wanna save about how far along they were in their song, you wanna save that information on stop. That's guaranteed to be called, okay? On destroy is most likely called and then the activity is gone, okay? So what does that mean? What is going on in Android land to make this happen? Well, let's recall the Android stack for just a moment. Remember, your application is gonna sit way up here at the top and there's all this other stuff down below that makes it work. The framework that you've gotten used to now with views and widgets and today we'll talk about the Android runtime a little bit. We're computer scientists. We should know a little bit about how Android is dealing with the code that you write, okay? So when you write a program, let's talk about what happens when you write a program in Android and the steps that have to happen to get it to run on a real device or a simulator, okay? When you're writing a program, a regular program in Java or Python or CC plus plus, there's a couple of steps, right? And there's a couple of layers to the actual machine that you're using, right? So you start by writing code in a programming language like Java and it runs in language specific code inside a virtual machine. Now a virtual machine is just, it's another program, first of all, and this code, the language specific code talks to the virtual machine kind of abstractly. It says, hey, I want the keyboard input. Hey, I wanna write to the display. Hey, I need to write to memory, okay? The virtual machine is virtual, but the nice thing about the virtual machine from a programming language perspective, Java has a virtual machine, Python kinda has a virtual machine, is that these run on any operating system, right? Windows, Mac, Linux, they all look the same to the programming language code, okay? It's a level of abstraction. Let's you write programming language code without having to worry about the details of whether you're writing that code for Mac, for Windows, for Linux, whatever, okay? The language specific code, this is often called byte code, gets compiled into native code, okay? Native code is stuff that Windows or OS X or Linux understands, okay? Specific operating and system instructions that are particular to a particular operating system. The operating system, its job is to translate this native code into machine instructions. So your computer has hardware in it, right? It's silicon and lightning, but the computer understands a language. And in CSC 242, computer organization, you were exposed to this, right? Machine instructions are binary. They're ones and zeros. And ultimately, these ones and zeros kinda get translated through your computer architecture and down into and gates and or gates and or gates and all that good stuff, right? But there's several layers of compilation. From abstract that can run on any platform down to stuff that's very specific to the hardware in front of you. Same thing in Android, okay? But these things have different names and you should know what these things are, okay? So the virtual machine that all Android applications that you write runs in is called the virtual or the Android runtime or the ART, okay? Android runtime. That's the virtual machine that Android programs run in, okay? The operating system for Android is Linux 4.4 or higher, right? That's what's on every Android phone. The hardware is particular, whatever particular model of phone you're running on, okay? And the Android emulator can simulate a variety of these different things for you, okay? All right, so the language you write in is Java. Java gets compiled into what we call Davelik bytecode. It's something specific for Android and I'll show you how it kind of fits together in a second. And these are things that Android runtime understands. It gives it commands. It handles things like life cycles. It knows how to draw widgets. All that stuff is encapsulated here. Then Android runtime converts this into an OAT file of a head time file, right? It's a executable language format which is like a standard format for creating executables, right? You know, the kind of files that run and do stuff. The Android runtime changes this into an EL or an OAT file which is in a particular format understood by Linux, right? Linux then takes this ELF file and compiles it into the machine instructions appropriate for your computer hardware, okay? So kind of interesting. There's a lot of stuff going on here. There's a lot of layers to write in code. And believe me, you wanna be up here writing this code. The folks, the good folks at Android take care of these layers, right? Davelik and OAT. And the machine instructions while translating that, that's what the Linux guys do, okay? All right, so let's walk through the steps of compiling for Android. Like when you hit the run button in Android Studio, what happens? It's a lot, it happens. But you should be familiar with it at a high level, okay? So when you're writing your code, you've got all these Java files. You've got libraries that you're using, those things that you import in your build.gradle and that you've been using so far. But they're just Java, right? Libraries, and then your resources, your XML files, any pictures that may be included in your app, sounds, that sort of thing. This is the stuff that you say, I need in my app. Okay, so you click run. First thing that happens is your regular old Java compiler, the one that you've used before, takes the Java files in the libraries and turns them into class files. This is what happens when you run any Java program. The special sauce starts to come in whenever to pack in these resources. So Android has this thing called the dex jar compiler, turns it into this dex file, okay? The dex file just packages up Java files and resources into, and this is the language, davlik bytecode. This guy right here, davlik. That's what dex is short for, davlik executable, okay? But it's an executable, okay? Specific, it's a mix of Java and these other resources, okay? So we're kinda, again, we're here, we're at this layer. We've got something that's very generic that Android systems themselves understand, right? It's like the common language that all apps that have ever been written for Android are translated into, no matter where, who wrote them. Okay, so the next thing is this AAPT package gets called on your bundled up file. Now at this point, this is kinda interesting. This is usually just one file. So all the things that you have written together, all these Java files, the libraries, the resources, they're all being smushed into one file, one big file, right? A couple megabytes usually. This packageer puts it together. Now this thing does some magic, but the most important thing it does is it signs your output. The output is called an APK, an Android package, okay? This is another executable, it's got your classes inside of it, but this is the thing that goes to the store, right? It goes to the store, this is what gets downloaded and installed on your application, chunk, to file. And it comes down and you install it and suddenly you have the app, okay? The packageer does something very important, which is it signs it, okay? So when you go to make an app and put it out in the public for the world to see, you have to sign it with a digital key that says, this is me, I have created this thing and I have put it up on the internet for you to download. And cryptographic keys, digital signings be what they are. People will know and the Google Play Store will know that that came from you because you have a private key that you're holding secret that you use to sign this thing, okay? So this package, you create this package. Now at this point, if you were working on a real app and you wanted to deploy it to people, you're gonna take this package and you're gonna upload it to the Play Store and Google will take care of distributing it for you. When you're dealing with debugging and running it on your own little device or the simulator, what happens is the APK gets sent or installed into the Android runtime. This is sitting here running on your phone. The Android runtime extracts the OAT file out of the package. And remember, OAT file, gotta go back here a few slides. This is the thing that's generic executable format that Linux understands, okay? Takes the generic format that Linux understands. There's a zygote process. This thing called a zygote, right? What's a zygote? When biology, it's like the most basic primitive form of life of which other, you know, your cells are gonna produce out of. There's a little zygote process and all that zygote process is, is basically an empty Android activity. It knows how to start and shut down. What it's waiting for is the details of how to fill in the blanks, right? That's what that reads from this OAT file. The Android runtime forks off a zygote process, fills it with the OAT file and now your app is a process on the Android Linux operating system, right? So if you go to like, you know, your task manager, is it not gonna show it? There it is, right? You know, if you go to your task manager in Windows, you can see what's running, right? Well, Android extracts out of this APK and executable understood by Linux, forks a zygote process and then the zygote kind of consumes the OATs and now your app pops up, okay? Crazy, it's crazy what happens when you hit the run button. Very complex process, right? Okay, so if you recall from the intent stuff from last time, you don't actually call like, if you want an activity to start, you don't call new activity. You say, I need a new intent and with this intent, I want you to start up this other activity and you call this specific start activity thing. Well, what you're doing is you are begging the Android runtime, hey, find an activity and start it out, load up a zygote process and fire it up, show it on the screen, okay? That's what you're asking it to do when you say start activity. Now in the Android runtime and on the Linux operating system, you have many different apps running. Each process, each app is its own process on the operating system. Oh, my process list is gone, okay? By default, when you have, now you may also have, and why did they do this? They isolate it for security reasons. We don't want Spotify's app talking to Android's app without our knowledge, right? We have Canvas here. Canvas shouldn't be touching reading your Spotify data. So the apps are isolated primarily for privacy reasons but also for reliability reasons. If Spotify crashes, we don't wanna mess up Snapchat, right? So every application gets its own process. Inside the process, every activity will run, okay? So in general, inside a process, so this is for Canvas, right? The Canvas process, you can have many different threads that are running, okay? You will have a main user interface thread and this is kind of important. Every process has a main user interface thread. In Java, the user interface is controlled by one thread, one process. But you can have many threads inside your process. Process is like a thread, is like a thread is like a process within a process, okay? If you take operating systems or parallel computing, you'll learn all about processes and threads but sometimes you wanna share the work, right? The main UI thread is what is drawing things on the screen and receiving user interputs and interacting with it but you may have other long running things that your app needs to do like backing up a database or downloading a file from the internet or uploading a file from the internet. Those things take a long time and you want to have them on different background threads, not the main user interface thread because if they're on the main user interface thread and they take a long time, what happens is your app freezes, right? And you've experienced this. That's what's happening. Some long running application is going on and you're sitting there furiously mashing the button, right? Like why isn't this thing locked up? Well, something is blocking the user interface thread. It can't respond. It can't accept your input. It can't display results. So Android allows you within your process for your app to have multiple different threads. And we'll probably, we'll get to interact with some of those later in the semester. So anyway, kind of wrapping up here, gone on for a long time. When we talk about the activity life cycle, what is causing these things is this environment here, the Android runtime. The Android runtime is being shared with all the other apps on your device. And even if you're using a simulator, right, that's not got anything on it, if you look at the processes that are running, there's actually a lot going on. There's a lot of these Android processes that are going on in the background. So the activity life cycle is about Android kind of managing when things are running, when things come on to the screen, when they leave the screen and so forth, all right? So in the lab, you will get some experience working with these different life cycle methods and they're gonna be important because as you go into developing more complicated apps, you're gonna find that figuring out when to save data, when to load data, when to stop drawing, when to start drawing, it becomes an important part to building a reliable application. All right, that's it for now. Have fun in your app development and I'll see you next time.