teaching machines

CS 491 Lecture 2 – PopMusic

September 8, 2011 by . Filed under cs491 mobile, fall 2011, lectures.

Today we continue our discussion of Android development and start to dissect the pillars of all interactive applications: the classes Activity and View. Before that, though, let’s gather some requirements and do some rough design for today’s app: a bubble-wrap popper. Partner up with a neighbor and take 5 minutes to answer some questions:

 

Activity

Class Activity is defined by the Android SDK as a single, focused task that directly involves the user. You can think of an Activity instance as a single screen or level in your mobile app.

For each app, there’s a main Activity that gets started when the app first loads. It very likely will spawn other Activitys to accomplish related tasks or subtasks.

Let’s see Activitys at work in the Google Maps app. Here I’m looking for directions from campus to the mall, and I get the route spelled out for me on the left. When I click on “Show on map,” a new Activity is spawned to show the route visually.

At least, I’m guessing that the developers used two Activitys here, because the spirit of an Activity is to be self-contained. If the UI changes drastically within an app, you are probably switching to a new Activity.

Before we write an Activity, let’s talk about attaching a UI.

View

Activitys are associated with a particular user interface. The OHA chose not to use Java’s Swing as their interface library. They rolled their own. The standard widgets are essentially the same, but the API is different.

The granddaddy superclass of all UI elements is View. To show read-only text, we use a TextView (similar to JLabel without an icon). To show editable text, we use an EditView (similar to JTextField and JTextArea). To show a list, we use ListView (similar to JComboBox). With these three classes alone, we can get a lot done. We’ll explore other subclasses later.

Layout

Widgets need to be arranged on the screen in a flexible manner. We do not hardcode positions with absolute pixel coordinates. Instead, we make our Views children of various layouts. We can arrange widgets in tables (TableLayout), in horizontal or vertical stacks (LinearLayout), or more wildly (RelativeLayout, FrameLayout, AbsoluteLayout, …). We’ll assign various layout parameters to our widgets which will control how they fill the space allotted to them by the layout.

Feet Wet

Let’s go ahead and flesh out some of these ideas in a novelty application. We’re going to write a real crowd-pleaser: a bubblewrap-popping application. In preparation for that, let’s actually write a little sandbox app that we can play around with code in.

AndyTest

I’m calling the sandbox app AndyTest. I create a new Android project for it and add the code below as the main Activity. We can explain this one later. It’s essentially a menu for a bunch of smaller testing Activitys we’ll write throughout the semester.

package org.twodee.andytest;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class AndyTest extends ListActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    String[] items = {
      "LifecycleTest",
    };
    setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items));
  }

  @Override
  protected void onListItemClick(ListView listView, View itemView, int position, long id) {
    super.onListItemClick(listView, itemView, position, id);

    try {
      Class<?> clazz = Class.forName("org.twodee.andytest." + getListAdapter().getItem(position));
      Intent intent = new Intent(this, clazz);
      startActivity(intent);
    } catch (ClassNotFoundException e) {
    }
  }
}

Event-driven Programming

In your previous programming experiences, you may have gotten control of your program right away in the main method. And you kept that control all the way until main finished. That’s not how UI-driven applications work. There’s no main method in our control. We just write what are called callbacks, methods that get called when the system detects certain events. This is called event-driven programming, and we’ll see this will form how we implement our Activitys.

Let’s make a new Activity called LifecycleTest. Activity has methods onCreate, onStart, onRestart, onResume, onPause, onStop, and onDestroy. These are all callbacks called by the Android system itself, not by us. They will be called when our app is created, started, restarted, etc.

Let’s override them in our subclass. Eclipse makes this easy: Source, Override/Implement Methods… And let’s have each pop up a little text blurb when it’s called. Text blurbs can be displayed with the Toast class:

private void log(String message) {
  Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}

Let’s call this method in each of the callbacks. Run it and see what happens! It should fail. We need to register each Activity in our app in something called the manifest.

<activity android:name=".LifecycleTest" android:label="LifecycleTest" />

Run it again. Hit back. Reorient the device. Lock the device.

The sequence in which these callbacks get called is outlined in the Android documentation:

It’s in these methods where we get control. Typically, we can focus on just three of them: onCreate, onPause, and onResume. The first is called to do one-time initialization and the other two will transition us in and out a paused state, such as when a phone call activity supersedes our game of Minesweeper.

PopMusic

Let’s write our bubblewrap-popping Activity in a new project. Let’s call it PopMusic. We’ll need the following resources the resources from popmusic.zip.

Where do we put the contents? Images go in res/drawable. Ideally, we’ll have different resolutions of these images for the different screen densities of the various Android devices. We’re not quite that sophisticated yet. By convention, the sound files go in res/raw, which holds files that have only one version used on all devices.

Now, we’ll need to complete the following tasks:

The code will be posted later, after we write it.

TODO

Haiku

Ludd beat up machines
Iron thieves with no wives, kids
“There’s no app for me!”