Android tutorial part 1 - Conway's Game of Life

Thursday 17th of April 2014 06:49:41 PM


  Toggle Advanced Options




  • Day One - Why build Conway's Game of Life for Google Android?
  • Day Two - Starting to build the application
  • Day Three - First run
  • Day Four - Wiring the initial UI together

This tutorial has a second part: Android tutorial part 2 - Conway's Game of Life.

Update on Saturday, February 18, 2012

Update on Wednesday, January 26, 2011

Update on Monday, December 20, 2010

Update on Saturday, November 13, 2010

Update on Friday, June 18, 2010


NotesMappr - Android app

NotesMappr is PolishedCode's semantic note taking app for Google’s Android platform. In other words, NotesMappr (see screen shot, below) is note taking that fits your brain.


NotesMappr - Semantic note taking app for Android


Main benefits

  1. NotesMappr can be thought of as the textual equivalent of mind maps and/or concept maps. In a nutshell, NotesMappr's powerful underlying data structure, topic maps, makes it possible to link your notes in any way imaginable.
  2. Furthermore, NotesMappr's integration with Freebase makes it very easy to complement and enhance your own notes with comprehensive and reliable external articles and (associated) images.
  3. Finally, a set of notes in and of itself is a valuable thing. However, said set of notes becomes more valuable if the notes themselves are related in an appropriate manner. In addition, context enables both easy and quick discovery of information saving you time. Furthermore, context enables you to expand your knowledge without the risk of your knowledge becoming disjointed or fragmented.

Main features

  1. NotesMappr provides you with both the ability to establish meaningful relationships between notes and subsequently navigate said notes in a very straightforward manner.
  2. NotesMappr enables you to complement and enhance your own notes with articles and images from Freebase, an open Creative Commons licensed repository of structured data of almost 22 million entities.
  3. In addition to (formal) associations, NotesMappr also features "WikiWords" (words with multiple capital letters in the body of a note) to create and link notes within their context. NotesMappr automatically turns said WikiWords into links to other notes - just tap a link to create the new note.

Now, imagine studying with this app at your disposal. Or researching. Or generally just compiling notes on whatever topic that interests you. Just think for a moment how useful this app would be. What are you waiting for? Get NotesMappr for your Android device, now. It’s free.

Android app on Google Play


Tutorial

Day One - Why build Conway's Game of Life for Google Android?

For reference sake, I've based a lot of the code in the initial part of this tutorial on what I read from the book "Hello, Android - Introducing Google's Mobile Development Platform," from The Pragmatic Programmers. However, the second part of the tutorial is completely unrelated to before-mentioned book and unique to my own learning experience.

Basically, my initial motivation to write this tutorial was one of self-interest, that is, when you are forced to document something that you are in the process of learning, it helps to reinforce said learning experience.

As a developer, I am always looking out for new and interesting technologies and it takes no real leap of faith to see that mobile computing (in all its forms) is going to outright dominate the field of software development for the foreseeable future - mobile is going to be big... really, really BIG!

Furthermore, in my opinion, the writing is on the wall, that is, Google's Android platform will be established as a major player if not the player within the mobile market within the next couple of years, eventually overtaking both Apple and RIM within the smartphone market. We're not there yet (and perhaps we shouldn't ever 'get there' completely - competition is good), but I do see it happening sooner or later.

Hence, this tutorial is aimed at developers that know how to download and install SDKs, have a reasonable level of experience with Eclipse and specifically Java (the language) but at the same time do not have any real experience (like me) at building applications targeting Google Android.

Why Conway's Game of Life? Well, Conway's Game of Life is a very simple cellular automaton (for a more in-depth overview of the game, check out the article at Wikipedia for Conway's Game of Life) - the problem space is small enough to allow me to only focus on Google Android while still including sufficient elements to make for both an interesting and valid learning experience. For example, the application includes:

  • a 'game' loop (in its own thread):
    • update state
    • update input
    • update calculations
    • update animations
  • GUI components with binding
  • a custom GUI component

Overview of application


Conway's Game of Life Java applet


Looking at the screen shot of my original Java applet-version of the Game of Life, the following components have been laid out (from top to bottom):

  • the actual (infinite) two-dimensional orthogonal grid of square cells
  • 'minimum' or underpopulation variable spinner (see Game of Life rules below)
  • 'maximum' or overpopulation variable spinner (see Game of Life rules below)
  • 'hit' or spawn (new cell) variable spinner (see Game of Life rules below)
  • animation speed or evolution speed variable spinner
  • cell shape drop-down (not to be implemented)
  • colour coded tick box (mapping the rate of survival to colours, that is, number of iterations that a cell has survived to a distinct colour) - to be implemented in version 1.1
  • iteration or generation counter

If you look at the above list of components, they are all standard widgets except for the first one - the two-dimensional grid. Off the top of my head after having skimmed over the Android Developer's Guide, I think I will need to implement my own custom component that will draw with a Canvas on a View or SurfaceView - not sure yet.

Furthermore, the actual layout declaration is very simple: a vertical layout containing the custom grid component, several (embedded) horizontal layouts for the sliders and their corresponding labels, the tick-box for enabling or disabling the colour-coding and the generation counter.

Algorithm

The actual algorithm used to generate each successive generation is (perhaps) surprisingly simple: the Life patterns are represented as two-dimensional arrays. Two arrays are used, the first one to hold the current generation and the second one in which the next generation is calculated. Obviously, a zero will be used to represent dead cells and a one will represent live cells.

Each cell will be iterated over - an inner loop will be used to count the number of live neighbours to decide if the corresponding cell will 'live or die' in the next generation. Once all cells of the current generation have been iterated over and the corresponding successor array has been calculated, the successor array becomes the current (generation) array and is displayed, i.e., the two arrays swap roles.

With regards to the edges, in theory, the Life grid is infinite - this however, is not practical. Hence, I have adopted the strategy of wrapping the grid around, that is, both the top and bottom and left and right edges run over into one another - a toroidal array (check out the article in Wikipedia, if for no other reason than that there is a cool animated GIF of a punctured torus been turned inside-out).

Basically, there are only four methods of importance from the point of view of the algorithm as outlined above:

  • nextGeneration: the so called driver method (the following three methods/functions are called from the nextGeneration method)
  • calc: this function actually determines how many live neighbours each individual cell has
  • duplicateGrid: this method copies the contents of one array to another array
  • initGrid: this method 'resets' an array, that is, it sets all of the elements of the array to zero

Obviously, it makes sense to encapsulate all of the above methods and any other helper methods into their own class.

Game of Life rules

See Wikipedia (copied here for reference purposes): Game of Life's rules.

The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square cells, each of which is in one of two possible states, live or dead. Every cell interacts with its eight neighbors, which are the cells that are directly horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur:

  • any live cell with fewer than two live neighbours dies, as if caused by underpopulation
  • any live cell with more than three live neighbours dies, as if by overcrowding
  • any live cell with two or three live neighbours lives on to the next generation
  • any dead cell with exactly three live neighbours becomes a live cell

Day Two - Starting to build the application

Today, I am actually going to start to lay out the application. I initially envisage the application having a main screen with the following UI elements laid out vertically from top to bottom:

  • A TextView component - the name of the application.
  • A Continue button - display the application's principal screen with the grid of cells (to display the Life patterns) and the various components that will allow the user to interact with the Life patterns - allowing the user to continue where she left off.
  • A New Game button - reset both the Life pattern and the accompanying components to their initial state.
  • An About button - self explanatory.
  • An Exit button - self explanatory.

Implementing the application as described above means that I will need to cover several important concepts of Android's application development model, specifically:

  • Activities: the application's presentation layer. Each and every screen in an application has to extend the Activity class. Activities use Views to make up graphical user interfaces.
  • Views: views are the graphical user interface (GUI) elements that make up the basic building blocks of a user interface. Each component knows how to draw itself - views themselves are hierarchical.
  • Intents: Intents are a message-passing mechanism that works both within an application, and between applications. One of the most common uses for Intents is to start new Activities.
  • The application manifest (AndroidManifest.xml): the manifest file defines both the content and behaviour of the application. For example, it lists the application's activities, services, and corresponding permissions.

Anyway, let's start...

I'll create the project with the following values:


Conway's Game of Life for Android - Eclipse New Project wizard


After having stepped through the New Project wizard, the project is created with the following files:


Conway's Game of Life for Android - Initial project files


Day Three - First run

Initially, the files of interest are:

  • MainActivity.java - as the name implies, the main activity/screen of the application.
  • res/layout/main.xml - the MainActivity's accompanying layout resource. If you think about it, UIs can be implemented using one of two methods: procedural (like Swing) and declarative (like HTML). With Android you can use both methodologies - in this case main.xml is the MainActivity's UI in declarative XML.
  • strings.xml - instead of hard-coding (in this case, English) text into the layout files, with Android you use the @string/resid syntax to reference strings in the res/values/strings.xml file (we will see examples of this in a minute).
  • AndroidManifest.xml - every activity (among other things) needs to be declared in AndroidManifest.xml.

Let's start looking at some code. I'll start with MainActivity.java:

MainActivity.java

package com.quesucede.gameoflife;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

There are a couple of important things going on here:

  • the MainActivity class extends the Activity class
  • the onCreate method is overridden; within said method a call to the super method is called with the appropriate parameter (savedInstanceState).
  • within the onCreate method, a call to setContentView fills in the contents of the activity's screen with an Android view; in this case, said view is defined in res/layout/main.xml.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/background" android:layout_height="fill_parent"
    android:layout_width="fill_parent" android:padding="30dip"
    android:orientation="horizontal">
    <LinearLayout android:orientation="vertical"
        android:layout_height="wrap_content" android:layout_width="fill_parent"
        android:layout_gravity="center">
        <TextView android:text="@string/main_title"
            android:layout_height="wrap_content" android:layout_width="wrap_content"
            android:layout_gravity="center" android:layout_marginBottom="25dip"
            android:textSize="24.5sp" />
        <Button android:id="@+id/continue_button" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:text="@string/continue_label" />
        <Button android:id="@+id/new_button" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:text="@string/new_game_label" />
        <Button android:id="@+id/about_button" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:text="@string/about_label" />
        <Button android:id="@+id/exit_button" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:text="@string/exit_label" />
    </LinearLayout>
</LinearLayout>
Relevant URLs

Again, let's take a look at a couple of interesting things in the main.xml file:

  • LinearLayout - layouts are hierarchical containers for objects with an associated positioning behaviour, e.g., LinearLayout positions its embedded objects in a single column or row.
  • A new syntax, @+id/resid - basically, this syntax allows us to create an ID in-line instead of referring to a resource ID defined somewhere else. For example, @+id/continue_button actually defines the ID for the Continue button so that we can reference it, later on.
  • android:layout_width="fill_parent" and android:layout_height="fill_parent" - indicates that the layout should take up the entire width and height of the parent view.
  • units of measurements, e.g., dip and sp - Android supports several screen resolutions and corresponding densities. The density of a screen is important because, other things being equal, a UI element (such as a button) whose height and width are defined in terms of screen pixels will appear larger on the lower density screen and smaller on the higher density screen. Resolution-independent measurements help solve this problem. Android supports all the following units:

    • px (pixels) - dots on the screen.
    • in (inches) - size as measured by a ruler.
    • mm (millimeters) - size as measured by a ruler.
    • pt (points) - 1/72 of an inch.
    • dp or dip (density-independent pixels) - the density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, the baseline density of Android. The conversion of dip units to screen pixels is simple: pixels = dips * (density / 160). For example, on 240 dpi screen, 1 dip would equal 1.5 physical pixels.
    • sp (scale-independent pixels) - similar to dp but also scaled by the user’s font size preference.

Using dp units and sp units (for text) to define your application's UI is highly recommended, as a way of ensuring that your interface is scalable to any current and future type of display.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Android Game of Life</string>
    <string name="main_title">Android Game of Life</string>
    <string name="continue_label">Continue</string>
    <string name="new_game_label">New Game</string>
    <string name="about_label">About</string>
    <string name="exit_label">Exit</string>
</resources>
Relevant URLs

The application's resource strings are defined in the res/values/strings.xml file. Each resource string has an accompanying name attribute for reference purposes. For example, within the main.xml, the TextView widget references the resource string main_title as follows: @string/main_title.

Basically, what this accomplishes is a decoupling of an application's resource strings making hard-coding of resource strings unnecessary. From a maintenance point of view of the source-code (or translation point of view of the UI) I can imagine that this is a real time-saver.

color.xml

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <color name="background">#596f87</color>
</resources>

The res/values/color.xml fulfills a similar purpose as res/values/strings.xml.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.quesucede.gameoflife" android:versionCode="1"
    android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest> 
Relevant URLs

Each Android project has a manifest file, AndroidManifest.xml located in the root of the project hierarchy. It governs both how your application's components (Activities, Content Providers, Broadcast Receivers, and Services) interact with one another and with other applications on the device by means of Intent Filters and Permissions.

In addition, the manifest also includes attributes to define application metadata (e.g., icon), and additional tags for security settings, hardware and platform requirements, etcetera.

It's important to remember that the Android Development Tools (ADT) plugin includes a visual manifest editor so that you don't have to edit the underlying XML directly.

Creating a new Android Virtual Device (AVD)


Conway's Game of Life for Android - Create new Android Virtual Device


Relevant URLs

Obviously, unless you have a physical Android device, you will need to prototype, debug and test your application on a virtual device with the Android emulator. The emulator enables the creation of Android Virtual Devices (AVDs) - a combination of a specific version of the Android platform, hardware options and emulator skin.

With regards to screen size (or emulator skin), I have opted for HVGA (320 x 480), 3.0"-3.5" diagonal - the Android's platform baseline screen (because all applications written against Android 1.5 or earlier are written for the HVGA screen used on the T-Mobile G1 and similar devices).

The application's initial screen


Conway's Game of Life - First Android screen shot


With the code as provided above, running the application from within Eclipse will deploy the application to the Android emulator and subsequently execute the application. The screen shot provided above shows the UI of the application's main screen. Obviously, at this stage, clicking on the buttons does not perform any kind of action within the application.


Day Four - Wiring the initial UI together

The first screen that I am going to wire up is the About screen. Initially, all that is needed is the About Activity (AboutActivity.java file) and its accompanying resource file (res/layout/about.xml).

AboutActivity.java

package com.quesucede.gameoflife;

import android.app.Activity;
import android.os.Bundle;

public class AboutActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.about);
    }
}

Nothing of interest here... move on ;-)

about.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:padding="10dip">
    <TextView android:id="@+id/about_content"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="@string/about_text" />
</ScrollView>

The only thing of interest in the about.xml file (provided above) is the in-line creation of a new resource ID (@+id/about_content) and an additional reference to a resource string (@string/about_text) meaning that I will have to add it to the res/values/strings.xml file.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Android Game of Life</string>
    <string name="main_title">Android Game of Life</string>
    <string name="continue_label">Continue</string>
    <string name="new_game_label">New Game</string>
    <string name="about_label">About</string>
    <string name="exit_label">Exit</string>
    <string name="about_title">About Android Game of Life</string>
    <string name="about_text">
The Game of Life, also known simply as Life, is a 
<i>cellular automaton</i> devised by the British mathematician 
John Horton Conway in 1970. It is the best-known example 
of a cellular automaton.
    </string>
</resources>

Finally, this is where things start to get interesting... an action needs to be performed when the user clicks on the About button. This is where intents come into the picture. Let's take a look at the modified MainActivity.java file.

MainActivity.java

package com.quesucede.gameoflife;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // click-handlers for buttons
        View aboutButton = findViewById(R.id.about_button);
        aboutButton.setOnClickListener(this);
    }

    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.about_button:
            Intent i = new Intent(this, AboutActivity.class);
            startActivity(i);
            break;
        }
    }
}
Relevant URLs

Let's take a closer look at MainActivity:

  • both android.content.Intent and android.view.View.OnClickListener are imported
  • the MainActivity class declares to implement the OnClickListener interface, specifically the onClick method is implemented
  • an OnClickListener is set for the About button (which is located by its ID (R.id.about_button)
  • within the onClick method a switch statement is used to determine which view (button) was clicked and depending on the button clicked (in this case, we have only set up a listener for the About button), an Intent object is created and the appropriate activity (AboutActivity.class) is passed to it followed by the activity being started by passing in the, previously created, Intent object

Running the application again and clicking on the About button will give you an error.


Conway's Game of Life - Android application error


What happened? Easy... every activity has to be declared in the AndroidManifest.xml file. So, let's add the appropriate entry to the manifest file:

AndroidManifest.xml - AboutActivity

<activity android:name=".AboutActivity" android:label="@string/about_title"
    android:theme="@android:style/Theme.Dialog">
</activity>

Furthermore, if you take a closer look at the above entry you will see that there is also a reference to a predefined style (@android:style/Theme.Dialog). What this means is that the AboutActivity will take on the look-and-feel defined by Android (with the @android prefix) instead of an arbitrary style defined by the application.

Executing the application and clicking the About button will display the screen as show.


Conway's Game of Life - About screen


Relevant URLs

This basically concludes the first part of this tutorial. The next part is going to be much more interesting and will include, among others, the development of a custom component (the two-dimensional orthogonal grid), binding components to data and threads.

This tutorial has a second part: Android tutorial part 2 - Conway's Game of Life.




Comments

A note of warning@10-05-31 23:08:04 by Brett Kromkamp

For anyone that stumbles onto this page... please keep in mind that this is a work in progress. Something that will be added to and updated over the course of the next few weeks starting from May 30, 2010.

Site comment system and moderation tool@10-06-02 23:43:37 by Brett Kromkamp

I intend to integrate DISQUS (a comment system and moderation tool) into my site within the next couple of days for feedback purposes. In the meantime, if you want to contact me with regards to the tutorial, send a mail to brettkromkamp@gmail.com.

Acknowledgement@10-06-02 23:19:09 by Brett Kromkamp

I've based a lot of the code in the initial part of this tutorial on what I am reading from the book Hello, Android - Introducing Google's Mobile Development Platform, from The Pragmatic Programmers.






Google