The Solution: Persisting Data12:53 with Ben Deitch
In this video we'll use Room to persist the note data.
implementation 'android.arch.lifecycle:extensions:1.1.1' implementation 'android.arch.persistence.room:runtime:1.1.1-rc1' kapt 'android.arch.persistence.room:compiler:1.1.1-rc1'
Now that we've got the UI working, let's get working on the database. 0:00 The first thing we'll need to do is add a couple imports to our build.gradle file. 0:04 I've already got them on the clipboard, but 0:09 they're the same ones we used in the pizza keeper app. 0:11 Then we need to sync the project, and we can close the build.gradle file. 0:21 Next, I'll add a data package, for organizing all of our database files. 0:27 And I'll start with the bottom, by creating entity to represent a note. 0:38 We call this class Note, then we need to make it a data class. 0:47 And instead of the brackets, we'll use the parenthesis, and then we'll give it an id. 0:52 And actually first let's give it the @Entity the annotation. 0:57 Then let's give it an auto generating primary key, 1:03 so this will be @Primary key, 1:08 autoGenerate = true, and we'll call it val id. 1:11 And it can be an integer which might be null, and 1:18 then we will have the text of the ID, which is a string. 1:22 Let's see what we've got here. 1:27 This doesn't equal an int, there we go. 1:28 I'll wind this up. 1:37 Awesome, so a really simple table for our note. 1:39 It's got an id which we're going to auto generate by passing in null, 1:42 and we'll store the text as a string. 1:45 Then we'll need a data access object to access our note. 1:48 So let's make a new interface. 1:52 This would be NoteDao, and let's give it the @Dao annotation And 1:56 inside let's write a get all function. 2:03 So that'll be query select star from, it'll be note. 2:07 And the function will be called getAll. 2:16 And you will want this 2:21 to return a LiveData 2:27 of a list of notes. 2:32 And then in order to have the OK button work, we need an insert function. 2:37 So we insert and fun insert takes in a note, and that's it. 2:41 Then to tie it in altogether we need a database class. 2:53 So lets create MyDatabase. 2:57 That will be a class and its actually an abstract class, 3:03 and we wanna use @Database, then we need to add the entities. 3:08 So, let's do this as an array of K classes, So, Kotlin classes, 3:14 meaning we do Note::class instead of class.java. 3:20 And then for the version, set it to 1. 3:25 And this needs to extend from RoomDatabase, 3:28 And the constructor invocation, then we need to add an abstract 3:35 function called noteDao, that returns a NoteDao. 3:40 Right, have to add the parentheses for our functions. 3:51 Okay, and that should do it for the database. 3:56 So now let's add the view model. 4:04 So let's add here a new view model class for our main activity, MainViewModel. 4:06 This is a class. 4:13 So I'll hide the project pane for a second, and 4:17 make this extend from the view model class. 4:19 And we'll need to add the parentheses, and then let's get to our view model. 4:26 Let's start by declaring a private variable, Named notes, 4:31 which is a live data of a list of notes of our note class. 4:38 So, just like we we're returning in the noteDao, 4:46 we'll give this the ability to be null, and initialize it to null, 4:50 and then we'll have a function to populate this notes variable. 4:53 So, let's do function, get notes, and 4:57 this returns a LiveData of a list of notes. 5:02 Though note, this one cannot be null. 5:11 And inside this function, if notes is null, 5:14 then we'll retrieve the notes. 5:19 And otherwise we will return, 5:26 The notes and assert that they're true, or rather assert that they're not null. 5:32 So inside here we'll need to add code to retrieve our notes from the database. 5:38 To get access to the database, 5:44 let's do the same thing we did in the Pizza Keeper app. 5:46 Let's create a new app class, Which extends from application. 5:49 And then let's override, so Control O The onCreate method. 6:04 And let's add our lateinit var db. 6:10 MyDatabase, so we are adding our database variable again, 6:21 scoped to the entire project, and we're using a lateinit. 6:26 So inside onCreate, before the call to supper.onCreate, 6:31 let's set db = Room, which we'll need to import .databaseBuilder. 6:37 And then provide a context, application context, the class of the database. 6:43 So MyDatabase::class.java, and the name of the database, 6:49 so, MyDatabase, and then we need to build it. 6:55 And since this comes before the call to super.onCreate, 7:03 we'll have access to our database from anywhere within the app. 7:06 Like in our main view model. 7:13 So if we call getNotes and notes from our view model is null, 7:15 let's go ahead and retrieve those notes from the database. 7:19 Let's set notes = db.otesDoa.getall. 7:24 Perfect. 7:30 Our view model is all set up ready to go. 7:34 Let's head back into main activity, and I'll hide the Project pane. 7:36 And below where we set our OnClickListener, 7:45 let's add a couple lines, and get access to our viewModel. 7:47 So, val viewModel = ViewModelProviders, 7:51 With an S, .of, and pass in this for 7:59 the activity, and then, .get, and 8:03 pass in MainViewModel :: class.java. 8:07 Then to get a live data of our list of notes we can call viewModel.getNotes. 8:14 And then to observe t we just need to add a call to observe, 8:22 pass in a lifecycle owner like the activity And then pass in an observer. 8:26 We can create a new one by just typing in, Observer, with a capital O, and 8:33 accepting Autocomplete. 8:37 Inside the observer, we are dealing with a list of notes that might be null. 8:41 So let's start by first making sure that list is not null. 8:45 If, it, not equals null. 8:49 Once we make sure that our list of notes isn't null, let's go into the adapter and 8:54 clear the list, and then add back in each of the elements. 8:59 So, we'll do adapter.list.clear, 9:03 and then adapter.list.addAll. 9:08 And we'll need to pass in the string portion of all of our notes. 9:12 So here we have a list of notes, so let's take this and let's call .map. 9:18 And this will take our list of notes and map it to something else. 9:25 So lets map it to it, so in here we have a note, let's take that .text. 9:29 And now we've taken our list of notes and transformed into a list of strings, 9:35 where each item in the list just contains the text of the note. 9:40 So once we've done that we just need to call 9:46 adaptor.notifyDataSetChange to make the changes happen. 9:49 And now that we're updating UI, based on our viewModel, 9:54 all that's left is that when we click the button, instead of updating the adaptor, 9:57 we should save to the database. 10:02 So let's delete these two adapter lines and call DB, or rather a new thread, 10:04 and inside that thread we'll call db.noteDao.insert. 10:11 And we'll have to insert a new note, so up here let's create a new note. 10:16 And for the ID we'll pass in null, and for the text, 10:19 we will give it, A value of note. 10:25 So we can't reuse this variable, so let's rename this one actually to noteText. 10:30 So this is used, noteText, noteText is now blank, 10:37 and that's all that's used for so let's pass noteText in there. 10:41 And we can input the note class, great. 10:45 Then we've got a note that we'll be inserting into our database. 10:49 And all right, let's see what it looks like. 10:58 And we're getting some error about a line we need to add to the build.gradle file. 11:03 Not sure what that's about, but we can do that. 11:10 And the app synced, so hopefully that took care of that issue, let's run the app. 11:21 And see what I did wrong. 11:30 It looks like our db variable was never initialized, and I think I know why. 11:45 I didn't add the application to the manifest, and 11:52 it warns me of that right here. 11:56 So we come into the manifest, we type android name and app. 11:59 Now when we run the app, we will at least get a different error. 12:05 All right we've got text let's type hello world and 12:10 hit OK, and it's in there. 12:15 And if we rotate the app it's still there, it's still there. 12:18 I'll send another message like, This is pretty cool, 12:23 and one exclamation point, and then we'll say OK, got that in there. 12:28 Still doing the rotation, let's leave the app using the back button, 12:35 cuz remember that will cause a full destruction of the activity, and 12:38 then let's reopen it Might be faster just to hit the Run button in Android Studio. 12:42 And awesome, there it is. 12:49
You need to sign up for Treehouse in order to download course files.Sign up