When you have more than a couple of data objects, you can manage them in app memory using Java collections. The most commonly used of these are the List and Map interfaces, using concrete implementations ArrayList and HashMap. The List is an ordered collection, like a resizable array, and the Map is an unordered collection of key-value pairs. If you’re unfamiliar with these Java interfaces and classes, you can learn about them in the course Java Essential Training, in the chapter “Using Data Collections”.
- View Offline
- [Instructor] Before you get started with saving data persistently on an Android device, you'll need a way to store that data in application memory. You can model your data in Android using standard Java design patterns. A simple Java class known sometimes as a data transfer object, a value object, or a Java bean, can be used to represent each instance of a particular data entity. Now these patterns aren't all exactly the same, but they have a common set of syntactical rules. The class is designed to store data in private fields, members of the class, and to make that data accessible to the rest of the application through setter and getter methods.
In my app, I'll be presenting a restaurant menu, and I'm starting in the project named Model Data. When I run it initially, it just displays a starting activity with the text, "Ready to code." Eventually, there will be a number of categories in my application, and each category will have a number of menu items. I might naturally want to name a class representing each item Menu Item, but that's the name of a commonly used class in the Android SDK. So to avoid a naming collision, I'll give my class a more generic name of Data Item, and I'll put it in a new subpackage named Model.
In the project window, I'll create that new package, and I'll name it Model. And then with the new package selected, I'll create the new Java class. And I'll name it Data Item. It won't have any specific superclasses, and it won't implement any interfaces. So I'll just click Okay to create the class. And then I'll delete the automatically created comment at the top. I'll create my first field. All of these fields will be private, following standard Java design patterns.
This will be a String, and I'll name it itemId. Now I'll duplicate that code a number of times. And then I'll rename the new versions. The second field will be named itemName, the third will be named description, and the fourth will be named category. And again, those are all Strings. The next field is going to be an integer. I'll give it a primitive type of int, and a name of sortPosition. Then I'll create a double field and I'll name that one price, and finally another String, and this one will be named image.
Now just one note about some of these types. The first field is named itemId, and it's a String. When I store this data eventually in a database, that field will be used as a primary key, a unique value that always identifies a particular data item. In some database environments, you might set this as an integer value, and that value might even be generated by the database engine. In Android though, it's a common practice to use String values as primary keys, and to generate those Strings as UUIDs, that is, universal unique Ids, string representations of 128 bit values that are guaranteed to be globally unique.
This uniqueness makes it easier to sync data between local clients and cloud-based services. My name, description, and category will also be String values. In a more fully realized application, the category might be a unique ID that can be joined to another table named categories. But for now, I'll just store the category name as many times as needed. The price is a numeric value, and I've set its type as a primitive double. As we'll see later, it's useful to limit yourself to Java's primitive types, plus Strings.
This makes it easy to pass data objects between the different tiers of your app. For example, a Java object with only primitives and Strings can be passed from one activity to another, and can be packaged in a broadcast message. If you use more complex types, such as big integer or big decimal, this is made more difficult. Next, I'll create constructors for this class. I'll have two constructor methods. One that receives no arguments, and one that receives one argument for each private field.
I'll go to the menu and choose Code, Generate, and then Constructor. And I'll hold Control or Command down and click itemid to clear the selection, and then click OK. And that creates the No Arguments constructor. Then a couple lines down, I'll repeat the operation, and this time I'll choose all of the fields, and click OK again, and that generates a constructor method that receives arguments for each of the fields and saves those argument values to the fields.
Next, I'll add setters and getters. I'll move the cursor down to the bottom of the class, then once again I'll select Generate, and I'll choose Getter and Setter, and choose all of the fields, and click OK. And that generates a whole bunch of code down here that allows me to set and get values from the rest of the application. And finally, I'll add an implementation of the toString method. Now, I could just start typing toString, and then select it from the pull down menu, but then I'd have to fill in the implementation myself.
Instead, once again I'll use the Generate tool. And I'll choose toString, I'll make sure everything is selected, and I'll click OK. And that returns a String that reflects all the current values for the current instance of the class. Now I'm ready to test my class. I'll go back to the main activity, and I'll place the cursor up here, above the declaration of tvOut. I'll declare an instance of my new data item class. Because it's in a subpackage, I'll need an import statement at the top of the class.
That's generated automatically as I type by Android Studio. I'll name the object item, and I'll use the version of the constructor method that receives all of those values. I'll set the item ID initially as null, then I'll set the name of the item as My menu item. And the category as simply a category. Then a description, and then the numeric values. For the sort position I'll pass in one, and for the price, 9.95. And finally an image name, and I'll pass an apple_pie.jpg.
Then I'll go down to the setText method call, for the tvOut object, that's a TextView, and right now, I'm using a String resource. I'll delete that, and I'll pass an item.toString. And I'll test my application. And there's the result. I've successfully saved data in the data item class. I now have a Java class that represents a single data item. To manage all of the data, I'll need to store multiple instances of that class, and I'll describe some good ways of doing that in the next video.
- Modeling data in POJO classes
- Customizing a ListView item display
- Displaying data in a RecyclerView
- Creating a custom array adapter
- Managing shared preferences with Java
- Creating and importing JSON data files
- Accessing SQLite from the command line
- Retrieving data with SQLite queries