Restoring State after Process Death (Do I need to care about process death?)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back to another part in the mvvm jetpack compose course for beginners in this part we're going to work on solving the problem of process death and if you don't know what process death is don't worry let's get into a demo right now and i will show you process death is a plague that affects all applications yes every single application you should have a strategy for handling process death so here we are in the app i'm going to scroll down to you know some page actually let me select a category because i want to showcase the the category information is also lost so i'm going to click on chicken here and now to trigger process death this is what you need to do there's a couple ways to do it but this is the way that i always do it so select a category let's you know scroll to somewhere in the app you know basically just do something in the app now send it to the background so i just clicked the uh the center button right here the home button and sent that app to the background now i'm on windows so i'm going to open up a windows explorer and i need to go to wherever platform tools is in my on my computer so for me that means going to users mitch appdata local android sdk and then platform tools so now inside of platform tools we can get access to adb we need to use adb because we need to access the the linux operating system that's working on the phone because we need to use that linux operating system to then kill the process that the app is running in on the phone so i'm going to write cmd here to open up a command prompt to this directory so now here i am inside of platform tools now i want to if you want to view all the kind of active processes that are running on the phone just write first of all adb shell to get into the adb shell you can see that i'm using a oneplus phone you can see there it says oneplus 5 that's the model of my phone now we're inside of we're essentially inside of like a linux terminal accessing the operating system on the phone so i can write ps for processes dash all and that's going to show all the running processes on my phone so these are like all the apps that are you know currently running on the phone there's a whole bunch of them not all of them obviously are ones that you've installed there's ones that just come with the phone so let me clear that by writing cls um oh that's not a command inside of linux sorry that was a windows what is it clr i don't remember okay i won't clear because i don't remember the command but now let's find the process that the app the mvvm app is running it so i'm gonna do ps dash all grep so grep is like a search and i'm gonna search for a certain package coding so com.codingwithmitch.mvvm recipes app i believe that that's the package recipe recipe app not recipes app so if i search that i should get one entry and there it is so now this is the this is the process uh which one is the process i think this one's the process id of the um the app that's running on the linux operating system i think that's the process id that might be the process id it doesn't matter it doesn't matter what the process id is one of those is the process id but it makes no difference we can now kill the process so kind of like kill the app by writing am kill and then comm coding with mitch dot mvvm recipe app so now if i if i type that and i and now i check for that process one more time so i'm doing ps dash a grep and then looking for the package notice it's gone the reason it's gone is because that process is is dead that app is killed essentially it does it is not running anymore so now if i was to look at our application again so i'm going to go to go to the phone and just relaunch the application so i'm clicking on mvvm recipe app now it's what what should happen is it should launch and be in the same state that that it was in before the process died but as you can see it's not we don't have our category selected the list position is like somewhere random it is it is not in the same state as when we left it so this is this is the quote-unquote process death issue if the user is using the phone and for some reason the process dies and we're going to talk about why a process might die in a second and the user reopens the app you know it's not in the same state it's kind of in some weird random straight state so this is obviously not a good user experience so the process doesn't just die like it's pretty uncommon for a process to die and i know this is this is sort of a heated topic like if you were to tweet at zwinden on twitter for example and to say like process death isn't a big issue he'd probably have a few things to say to you but in my opinion honestly process death is not a very big issue like it should be handled for sure but it's it's not that easy for the process to die modern phones have a lot of resources they have a lot of ram they have good hardware it's very hard for the process to die the only way a process dies is if you start running low on resources and it starts cleaning up the apps that are running in the background or maybe not being used and it would then kill the process to free up resources this is not as easy you know it doesn't happen that often i did a test for example one time i tried i had an app open and i was trying to get the process to die i had the pro the app open i opened up instagram facebook twitter youtube i opened up a whole bunch of apps oh google maps also i searched for locations on google maps i played around with facebook i played around on youtube i was downloading videos on youtube i was watching stories on instagram i even tried to upload i even uploaded an image to google maps so like that is a very resource intensive operation i did all of those things and the app still didn't kill the process so it's it's not as easy for the process to die as you might think but again it is something that should be handled because it it can happen all right so now let's uh let's handle process death so let's go into recipe list event and let's create a new event this event will be called restore state event and it'll be a recipe list event just like the others and i'll write a little comment here that says restore after process death so the the aim of of this you know process death restoration process is we want to save any of the arguments that are needed for any particular fragment or view and then when the process is restored we want to use those arguments to kind of restore the state of the app into what it was before the process died so let's go into recipe list view model and we're going to use something called the saved state handle so i'm going to write at assisted and don't worry i'm going to explain this it's going to look a little weird first but again i will explain this so just hang on do assisted private value saved state handle and then just call it save state handle so what is this save state handle and why did i use this weird assisted annotation well let's refer to the documentation so here we are in the documentation for saved state handle it's uh the url is up here it's just reference android x lifecycle saved state handle so if we scroll down to the description here it says a handle to saved state passed down to the view model you should use saved state viewmodel factory if you want to receive this object in the viewmodels constructor this is a key value map that will let you write and retrieve objects to and from the saved state so um oh also here this is important these values will persist after the process is killed by the system and remain available via the same object so this is very important so not only you can think of this as like a better version of saved instant state so in the past we had that you know saved instant state function that's available in fragments in activities we would pass key value pairs to that instant state and you know after the rotation aka the fragments destroyed the activity is destroyed those arguments then get restored so this is kind of a newer a newer and improved version of that because it will not only restore after uh you know configuration changes or whatever it will also restore after process death so that's a very very important thing so now what about this uh you know assisted annotation thing here well if you go back to the documentation here again notice here when it said you should use save state view model factory if you want to receive this object in the view models constructor so that's what we're doing here we have you know the save state being passed as a constructor argument to the view model so how does the view model know you know where to get this thing so by default it doesn't that's the punch line but because we are using hilt and view model inject on the constructor of the view model we can very easily just inject it using at assisted and it will automatically kind of magically be available to us if we weren't using hilt and we didn't have the view model inject annotation this would not work we would not be able to just pass it as a constructor argument we'd have to build a factory we'd have to build a view model factory it would be a much more involved process so hilt really makes things very easy for us okay now let's work on saving those key value pairs so come up to the top here and create some constants and i'll skip the video ahead here because i don't think it's really necessary for you to watch me type these out so we need four keys one to save the page one to save the query one to save the list position and one to save the selected category so when you're defining you know the keys of the things that you need to save you just need to think like what are the things in the ui that i'm going to need to restore after process death so for us the things that matter are the page so we know like the pagination system like which page we're on we need the query because that shows like up in the top bar like in the finished version of the app if we had a search being done we would need to know what that query parameter is we need to know what the list position is because if i was you know scrolled to some place we need to have that location restored after process death so that's the list position and then also the selected category so that is the the essentially the chip that is selected up here because that still needs to be highlighted after the process or after the state is restored after process death now i'm going to build some setter functions so that every time any of these parameters change like the the page the query the list position the selected category anytime those things change they will automatically be updated in the saved state handle so scroll down to the very bottom and do private function let's do set list scroll position and do position and that will be an integer now do recipe list scroll position equals position and then do saved state handle and do start set and do state key list position so stay keyless position and then just pass that position now you're probably thinking mitch this looks awfully like another function that we wrote let me scroll up it looks like this one right here it's doing the exact same thing and yes you're right that's why in here now what i'm going to do is call set list scroll position and then just call position equals position so essentially we've delegated what what this function did to this setter function which will also save it to the saved state handle now keep in mind i also like i know like if i wanted to i could have just you know taken this stuff and whoops i passed it and just put this in here that would have been the exact same thing but for me personally i like to kind of separate separate out uh what specific functions are for so for this one this is for you know what happens when we change the scroll position well there's two things that actually need to happen which is you know updating the scroll position and also updating the save state handle just a convention that i like to follow it's up to you you could have put both of them into the other function it doesn't really matter so now i'm going to write to the next one so private function will do set page and we're doing the exact same kind of thing here this dot page dot value equals the page then updating the saved state handle whoops saved state handle due dot set then state key the page and then do page on to oh actually then we need to call set page in the on increment page function or increment page function so set page and then just do page.value plus one so exactly the same kind of thing as we did with the on change recipe or on change recipe scroll position function next private function set selected category this will take a food category as input and this will be nullable now do selected category.value equals the category and then then do saved state handle dot set state state key selected category comma and then pass that category now look for wherever we set the value so selected category.value look for that and we're going to replace that so set selected category and then pass null now look for the next one um was there just one there should be more right here selected category.value so set selected category uh select category.value and then get rid of that previous line there whoops this should actually be this should be new category so new category and i think that was it let me see uh let's just look for selected category.value again yep that should be good so now on to the next function next one will be the query so private function set query this will be query and it will be a string open this up this dot query dot value equals the query and then save state handle saved state handle dot set and we have the state key for the query and then just pass that query then of course look for anywhere that this was called so this query.value just do a search for that come up here set query this and just set it to whatever that query was and we can delete that call whoops delete that call so again just looking for query and that should be good so just that one place was was calling that so now no matter what whenever any of these parameters change they will also be updated in the save state handle so now what about restoration this deals with you know keeping track of the values but how do we actually restore them so let's go up into the init function and above the on trigger event now we want to call you know save state handle for each one of our each one of our key value pairs for the first one we'll do an integer and do state key state key for the page and if that value is not null so let's check for that value and see if it's null get p which will be the page do uh set page and then that will restore the page when the view model is built so if the process dies basically the view model will be destroyed and then when the process is recreated the view model will be recreated and it's going to check for our key value pairs inside of the init function now we need to do the other three so i'm just pasting this three more times i'm going to change the argument this one will be you know state state key query so state key query this will not be p anymore let's do q and then just do set query and set that equal to q now the next one here we'll do another integer and this will be the list position so state key list position we can do p here again i guess for list position and then here we'll do set list scroll position set that equal to p and then the last one here this will be a food category whoops food category we'll do state key state key food or selected category and instead of p we'll do c for category and then just do set selected categories so set selected category and then c and then that new search event will be triggered so actually that doesn't make sense either because if the process died and if it is restored we don't want to do a new search event we want to restore the previous state so how do we know if you know the process died if we were currently we were doing something before and the process died we can check the scroll position so i can say recipe list scroll position if that does not equal zero then we know that the user was doing something they were scrolling around they were just doing something i guess that's really all it means so else will on trigger the event for the new search event and then if they were doing something so currently before the process died they were doing something then we want to just restore the the uh the state so we're going to call our restore state event uh case inside of our recipe list event class here so now we need one last function and that's the function that is going to be called when we restore the state so let's come down here and add a new case inside of our ontriggerevent this will be the restore state event and we need to call a new function that we're going to build so we'll call it restore state we haven't built this yet we're going to build this right now so private suspend function we'll call it restore state it will take nothing return nothing do loading dot value and set that equal to true now this is a little tricky because in the api you can only retrieve like each page of results per request so what we need to do is retrieve the results for each page like if the user was viewing page three we need to get page one page two page three and append them all to a single list so do value results this will be a mutable list object mutable list of recipes set that equal to mutable list of now i want to do four page in one up until page.value so we're going to search through each page and query the api now keep in mind in you know a production application we wouldn't be doing this we wouldn't be you know iterating through each page and then querying the api what would what we would have done is we would have cached those results into the local database and we would be retrieving them from the cache we would not be querying the api but because we don't have a cache in this app obviously we have to get it from the api also you might be thinking why didn't we save the list to the saved instance date or to the save state handle that is a no-no there's a limit to how much data you can save in the save state handle two megabits i believe is the the maximum which is only 250 kilobytes so if you had a list of data that is very easily gonna go over that limit i think probably you know depending on the data structure but very unlikely that it's going to hold more than you know 100 list entries so it's just not never save list entries to the save state or the save state handle that's a big no-no because you're gonna go over the limit so what you have to do is do what we're doing here you save the query you save the page number and then you re-query it from the cache in our case we don't have a cache so we're querying it from the api so now value result equals repository dot search token equals the token the page equals p from the loop up above query equals query dot value so that'll be the first page of results or whatever loop iteration we're in and then do results.add all and add the result that'll add you know list entries 0 to 30 and then the next loop entry will be you know 30 to 60 next will be 60 to 90 and so on and so on depending on how many pages the user had scrolled to so do p equals page dot value so if p equals the current pagination that means we're done so here i would write you know done we've got all the we've got all the recipes and in that case we would do recipes dot value equals the results and then also we could finish loading so do loading dot value and set that equal to false so that should be it if i'm not mistaken i think i think we're good to go here so i guess let's run it and we'll see if i made any mistakes all right so here's the app running let's perform a search so i'm going to click on chicken and i'm going to scroll down so i'll be page number two scroll down let's go to page number three just want to make sure that we you know get a whole bunch of results so i can really see if the process was restored or the state was restored now let's open up the command line i'm going to first take a look and see if we well actually sorry first i want to send this to the background so remember to test process death you've got to send this thing to the background now we open the command prompt and i'm going to click enter and see if that process is running yes there we go we do have a process running now i'm going to kill the process so am kill and then the process name now i'm going to check again to see if that process is running no it's not running so we know that yes we have successfully killed the process now we're going to relaunch the application so let's go to the app here i'm going to pull this up launch the app and we should be in the same state as when as before the process died so it looks good right away we see that the the search chicken is up here we see that our category is still selected and also the list position is restored this is exactly how we left the app before the process died so that's it we have successfully handled process death if for some reason the phone decided that we don't have enough resources to run this app kills the process if the user reopens it it's still going to be in the same state as when they left it before i go i just want to mention or i want to remind you that process death isn't that big of a deal it's actually very very unlikely that the phone is going to kill the process but it does happen it is something that should be handled it happens but again it's very very unlikely and if you think about you know most use cases also like if the user is doing something for the phone to kill the process it's probably because they sent it to the background they forgot about it for like an extended period of time the app said okay they obviously don't care about this so let's kill the process they probably aren't even going to care they're probably going to open it up and say oh i haven't opened this for a while hmm it's not in the same position oh well i they must have you know i don't know it seems like it seems like not a big deal but again it's it is something that needs to be handled now you know how to handle it don't forget your like don't forget your engagement leave me some kind of random engagement doesn't matter but you must leave some engagement you can tell me what you had for breakfast you can tell me what you had for lunch you could even tell me what you had for dinner or dessert tell me something engage with the video thanks for watching and i'll see you in the next one hey what are you still doing here the video is over well since you're still here i guess i'll show you the best android courses that exist on the planet i got all kinds of high quality courses if you scroll on down on the home page there's the jetpack composed one that you're watching right now there's that course we have mvi architecture if you've ever been curious about that we have my classic powerful android apps with jetpack architecture this shows you everything from well the focus on this one is pretty much database catching caching we get data from a real api we cache it we basically design an app to work when there's no network connection that is what this project is all about we have some ui testing another ui testing hilt which we actually went over in this course we got clean architecture this one's probably the best this is definitely the best course on my website if you are a professional or you are looking to get into the industry the skills that you learn in this course are absolutely fundamental this will give you a big edge in any job environments whether you're applying or you're already at a job and you want to just improve your skills this is a really really really high quality course it's hard your brain might explode while watching it but you will learn a lot you'll learn a lot of really really fundamental skills you know anything from getting data from the network caching data designing different layers abstracting out the different layers so you can write unit tests espresso tests so ui tests dagger navigation components everything it's beautiful definitely this is the best course on the website
Info
Channel: CodingWithMitch
Views: 2,751
Rating: 5 out of 5
Keywords: jetpack compose process death, android process death, do I need to worry about process death?, android process death jetpack compose, jetpack compose saved state handle, saved state handle, android saved state handle, android test process death
Id: mnQ2s0w209M
Channel Id: undefined
Length: 23min 6sec (1386 seconds)
Published: Thu Jan 14 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.