JSON and Final Project UI
Today’s lab marks the beginning of the end of your introduction to computer science. You’ll begin preliminary work on your final project, learn about JavaScript Object Notation (JSON), and gain insights into how to design a user interface.
Note that there is no written part of this lab. Instead, we’ll expect you to seek out any required information yourself or consulting your lab members for help.
1. Pair Programming
You’ll work in pairs on today’s activity. You should pick with and work with your final project partner. And you’ll also have a chance to practice a programming approach called pair programming.
1.1. Picking a Project Partner
Today you should pick someone that you will work with on your final project and in lab together for the next few weeks. Obviously you want to find someone to work with that you enjoy working with and think that you can do an awesome project with—since we will be giving extra credit for some of the best projects. Another consideration is ensuring that at least one of you has a laptop that can smoothly run Android Studio and the emulator, or an Android phone for demoing your new application.
If you don’t have a partner yet, find one before proceeding.
If you would like to work with someone from another lab section, you must both attend the same lab and work together. This means that only one of you will receive participation credit for that lab. You will not receive credit for working in lab without your partner. If you want to work with someone from another lab, this is the tradeoff you will have to make. (Remember that you have three excused lab absences.)
1.2. Pair Programming
By now you’ve probably realized that programming is a mentally taxing full-brain activity. So, frequently when programming, two heads are literally better than one. That’s where the idea of pair programming comes from.
What is pair programming? Simply put, it describes any programming approach where two programmers work together simultaneously using a single machine. No—you don’t type with all four hands 1. Instead, pair programming divides the work into two roles:
-
Driver: this programmer touches the keyboard and does all code editing tasks.
-
Observer: the second programmer does not touch the keyboard but rather observes what the driver is doing, reviewing each line of code, asking questions, and generally serving as a guide and check on what the driver is doing.
As a metaphor, think about the process of navigating a vehicle before voice navigation 2. One person, the driver, keeps their hands on the wheel and their eyes on the road. The second person, the navigator, is able to observe the surroundings, look at the map, and generally help keep the trip on track.
Pair programmers should switch roles often, and you should multiple times as you complete the lab tasks below. Pair programming is widely used in industry, partly because it is sometimes considered to produce better code, but mainly because it’s more fun than working alone.
Why are we doing this today? Simple: we want to help make sure that you and your partner can communicate and work together effectively. Pair programming forces you to communicate with your partner. If you are driving and not communicating, your observer has no idea what you are trying to do. If you are observing and not communicating, your driver has no way to incorporate your guidance.
So please complete the following tasks using pair programming. Each group should only have one laptop active and the other put away.
2. JSON (20 Minutes)
Object-oriented languages make it easy to model data internally by designing classes. But at times we need to exchange data between two different programs or systems, possibly implemented in different languages. That requires representing the data in a format that both systems can understand. JSON (JavaScript Object Notation) is one popular data exchange format in wide use on the internet, and frequently used to communicate with web APIs.
JSON is both simple and incredibly powerful. It is based on only two different principles, but can represent a wide variety of different data.
A requirement for your final project will be using data from a web API—we’ll do a bit of that today and more in the next lab. Many web APIs return data in JSON format, so you’ll want to begin familiarizing yourself with it today.
2.1. What is JSON?
Imagine we have an instance of the following Java class:
public Person {
public String name;
public int age;
Person(String setName, String setAge) {
name = setName;
age = setAge;
}
}
Person geoffrey = new Person("Geoffrey", 38);
Now image we want to send this information to another computer program. How do we represent this information in a way that is correct and complete, yet also portable.
JSON (JavaScript Object Notation) has become a popular answer to that question. While it is named after JavaScript, the language that introduced JSON, JSON is now supported by pretty much every common programming language. This allows an app written in Java to communicate with a web API written in Python, or a web application written in JavaScript to communicate with a web backend written in Rust.
Enough talk. Here’s how the object above could be represented in JSON:
{
"name": "Geoffrey",
"age": 38
}
JSON has only two ways to structure data: objects and arrays.
Above you seen an example object.
Like Java, it has named variable (name
, age
) each of which takes on a
particular value ("Geoffrey", 38).
Here’s another example.
The following instance of this Java object:
public Course {
public String name;
public int enrollment;
public double averageGrade;
Course(String setName, String setEnrollment, double setAverageGrade) {
name = setName;
enrollment = setEnrollment;
averageGrade = setAverageGrade;
}
}
Course cs125 = new Course("CS 125", 500, 3.9);
would be represented as this JSON string:
{
"name": "CS 125",
"enrollment": 500,
"averageGrade": 3.9
}
JSON can also represent arrays. This Java array:
int[] array = new int[] { 1, 2, 10, 8 };
would be represented using this JSON string:
[1, 2, 10, 8]
We can also represent nested objects and objects with array instance variables:
public Person {
public String name;
public int age;
Person(String setName, String setAge) {
name = setName;
age = setAge;
}
}
public Course {
public String name;
public int enrollment;
public double averageGrade;
public Person instructor;
public int[] grades;
Course(String setName, String setEnrollment,
double setAverageGrade, Person setInstructor,
int[] setGrades) {
name = setName;
enrollment = setEnrollment;
averageGrade = setAverageGrade;
instructor = setInstructor;
grades = setGrades;
}
}
Course cs125 = new Course("CS 125", 500, 3.9,
new Person("Geoffrey", 38), new int[] { 4, 4, 3 });
{
"name": "CS 125",
"enrollment": 500,
"averageGrade": 3.9,
"instructor": {
"name": "Geoffrey",
"age": 38
},
"grades": [
4,
4,
3
]
}
2.2. Parsing JSON
Because JSON is supported by many different programming languages, many web APIs return data in JSON format. To utilize this data, you must first parse it or deserialize it. The process of converting a Java object—or object in any language—to JSON is called serialization. The reverse process is called deserialization.
Happily, good libraries exist to parse JSON in every programming language. Java is no exception. One example is the GSON JSON parsing library from Google.
One way to use GSON is to create a class that matches your JSON string. So if you were provided with this JSON from a web API:
{
"number": 0,
"caption": "I'm a zero"
}
you would design this Java class to represent it:
public class Result {
public int number;
public String caption;
}
Note how our classes mirrors both the names (number
, caption
) and types (int
,
String
) from the JSON result.
However, when you are working with unfamiliar JSON data we suggest that you not create new classes and instead use the built-in Java classes. Here’s an example of how to do this given the JSON string shown above:
JsonParser parser = new JsonParser();
JsonObject result = parser.parse(jsonString).getAsJsonObject();
int number = result.get("number").getAsInt();
String caption = result.get("caption").getAsString();
In our example below the Volley library already returns you a JSONObject
from
your API request, meaning that you can begin exploring it without parsing it to
a String
.
3. DIY UI (60 Minutes)
Your first pair challenge for today’s lab is to add a user interface (UI) to a simple Android app.
We’ve set up the app to look up the location of different Internet Protocol (IP)
addresses using
https://ipinfo.io/.
Currently it just looks up a single fixed IP address on startup: 192.17.96.8
,
which is a very special and important IP address.
But currently the app has no way to take input from the user or display results. It’s missing a UI! So that’s your challenge.
Note that this is far from easy. If you have never done UI design before, you will soon gain an appreciation for how hard it is 3. And you’ll quickly develop an appreciation for all of the beautiful and well-designed apps that you use on a regular basis. Design is hard!
Another reason that we are doing this MP now is that we want you to come up with realistic UI goals for your final project. That’s what we’ll work on during the second part of today’s lab.
3.1. Forking and Cloning the Lab11 Android Studio Project
We’ve set up an Lab 11 GitHub repository containing an Android Studio Project that’s correctly configured for Lab 11. Getting access to it is similar to how you imported MP0. But you have to fork our repository first. If it’s not obvious how to do that, try following these instructions.
Note that you should use Android Studio for this lab. We’re done with IntelliJ at this point.
3.2. Examining the Existing Layout
We haven’t really provided much for you to start with for Lab 12.
But go ahead and open up res/layout/activity_main.xml
and examine the
skeleton that we’ve provided.
3.2.1. Design view v. text view
When working with Android UIs, it’s important to understand that Android uses its own kind of markup language to design user interfaces. Just like HTML determines the structure of a web page, Android uses XML to define and position layout elements.
Android Studio always provides two ways to examine the layout: one is the design view that shows a graphical representation of how the UI will look. The second is the text view that shows the XML markup used to generate the layout.
As you get started with UI design, we suggest using the design view as much as possible—it will make things easier. But if you want to continue Android development you’ll want to get comfortable with the XML view as well, and may want to learn how to design UIs by writing the XML directly.
3.2.2. LinearLayout
Your app’s MainActivity
currently uses a single UI layout called a
LinearLayout
.
It arranges all elements inside it into a single row, either horizontally or
vertically.
A LinearLayout
is not suitable for more complex UI designs, but it can be a
decent starting point for simple applications.
3.3. Android Design Principles
Roughly speaking we can break the available Android UI components into three categories:
-
Layouts: these determine how the elements inside them are positioned. Examples include the
LinearLayout
, the newConstraintLayout
, as well asFrameLayout
andTableLayout
. Layouts are largely invisible to the user. -
Containers: these determine how a larger amount of content is displayed, for example by scrolling (
ScrollView
,HorizontalScrollView
), in a drop-down menu (Spinner
), or by using tabs (TabLayout
). Containers may have navigation elements that are visible, like a scroll bar, but mainly exist to organize the things that they contain. -
Components: these are everything that is actually visible to the user, including images (
ImageView
), buttons (Button
,ImageButton
), progress bars, text input fields, etc.
One way to approach Android design is to start by answering the question: what will the user see or interact with? Then pick which component to use. Next, figure out how to use the containers or layouts to adjust where the component appears on the screen. More often than not, that’s the really tricky part.
3.4. Part 1: Button
To begin, add a button to the UI. Have that button trigger a lookup of some IP address. Feel free to look at previous labs and MPs for help. When the button is clicked you should see something like this printed in the logs:
D/Fall-2018-Lab11:Main: {
"ip": "192.17.96.8",
"hostname": "cs125-stu-01.cs.illinois.edu",
"city": "Urbana",
"region": "Illinois",
"country": "US",
"loc": "40.1106,-88.2073",
"postal": "61801",
"org": "AS38 University of Illinois"
}
I/Fall-2018-Lab11:Main: cs125-stu-01.cs.illinois.edu
This is the data in JSON format returned by the web interface that your app is using. You’ll learn more about web interfaces in our next lab.
Note that each UI element that you want to access in your code must have a
unique ID.
You can can elements whatever you want, but a good name for this button might be
lookup_address
or something like that.
It’s good to pick a meaningful name so that you remember what the button is for
what you are adding code to your MainActivity.java
class.
Here are the steps required to add the button:
-
Add the button to the UI. You can do this easily using the UI designer.
-
Make sure that the button has useful text and a useful ID.
-
Register a click handle for the button in your
onCreate
method, similar to what was done for MP4 and MP5. -
Have that click handler run the function that retrieves information about the current IP address.
3.4.1. Viewing the XML
When you’re done with adding your button using the UI designer, flip over to the text view and take a look at what’s there now. Try to get a general understanding of how the various components fit together. Try changing a few of the XML properties and see if you can alter how things look on the display, and gain an understanding of what each property is for.
3.5. Part 2: Location Display
Next, find a way to display something about the location of the IP address on the user interface. You’ll need to parse a portion of the retrieved JSON and stick it into a text box. We’ve provided a starting point as an example.
4. Final Project Planning and UI Mockup (30 Minutes)
You and your partner should use the remaining lab time to begin work on two important final project objectives.
First, you should decide what you are going to try and accomplish. Keep in mind how much time and energy you have left, your relative ability levels, and how much you want (or need) 1% extra credit. We also highly suggest working on a project that you enjoy. Excitement about the final product is extremely important to get you through the inevitable moments of frustration.
Once you have decided on a final project idea, you should begin sketching a user interface for your app. Please use this lab to inform your UI design. If you have some experience in this area, or just really like what you did for the first hour, then by all means consider something a bit complicated. If you struggled, stick with something simple. Note that Android provides some built-in activities that come with basic layouts designed for certain types of apps. You can explore those by right-clicking on your project, choosing new and then either activity or Google, which also contains some starter activities.