Professional Documents
Culture Documents
In this tutorial series, you’ll become familiar with Java, the programming language used to develop Android
applications. Our goal is to prepare those already familiar with one programming language, such as PHP or
Objective-C, to become comfortable working with the Java programming language and dive into Android app
development. In this tutorial, you’ll get a brief introduction to Java fundamentals, including object oriented
programming, inheritance and more. If you’re new to Java, or just looking to brush up on the details, then this is
the tutorial series for you!
Getting Started
As far as prerequisites go, we’re going to assume you understand how to program (perhaps in PHP, or Visual Basic
or C++), but that you are unfamiliar with the specifics of programming in the Java language. We aren’t going to
teach you to program; we’re going to provide you with clear examples of commonly used Java language constructs
and principles, while pointing out some Android-specific tips and tricks.
What You’ll Need
Technically, you don’t need any tools to complete this tutorial but you will certainly need them to develop Android
applications.
To develop Android applications (or any Java applications, for that matter), you need a development environment
to write and build applications. Eclipse is a very popular development environment (IDE) for Java and the
preferred IDE for Android development. It’s freely available for Windows, Mac, and Linux operating systems.
What is Java?
Android applications are developed using the Java language. As of now, that’s really your only option for native
applications. Java is a very popular programming language developed by Sun Microsystems (now owned by
Oracle). Developed long after C and C++, Java incorporates many of the powerful features of those powerful
languages while addressing some of their drawbacks. Still, programming languages are only as powerful as their
libraries. These libraries exist to help developers build applications.
Some of the Java’s important core features are:
• It’s easy to learn and understand
• It’s designed to be platform-independent and secure, using
virtual machines
• It’s object-oriented
Android relies heavily on these Java fundamentals. The Android SDK includes many standard Java libraries (data
structure libraries, math libraries, graphics libraries, networking libraries and everything else you could want) as
well as special Android libraries that will help you develop awesome Android applications.
Why is Java Easy to Learn?
Java is easy to learn for a variety of reasons. There’s certainly no shortage of Java resources out there to help you
learn the language, including websites, tutorials, books, and classes. Java is one of the most widely discussed,
taught, and used programming languages on the planet. It’s used for many different types of programming projects,
no matter their scale, from web applications to desktop applications to mobile applications.
If you’re coming from a traditional programming background like C or C++, you’ll find Java syntax quite similar.
If you’re not, then take comfort in knowing that you’ve chosen one of the easiest languages to learn. You’ll be up
and running in no time at all.
Finally, Java is one of the most human-readable languages out there, by which we mean that a person who knows
nothing about programming can often look at some Java code and have at least an inkling what it’s doing. Consider
the following example:
char character = 'a';
if(character=='a')
{
doSomething();
} else {
doSomethingElse();
}
the code aloud, you can pretty much tell that this snippet of code is doing. There’s a single letter variable called
character. If the character variable equals the letter a, then we do something (call the doSomething() method),
otherwise we do something else (by calling the doSomethingElse() method).
Why is Platform Independence Important?
With many programming languages, you need to use a compiler to reduce your code down into machine language
that the device can understand. While this is well and good, different devices use different machine languages. This
means that you might need to compile your applications for each different device or machine language—in other
words, your code isn’t very portable. This is not the case with Java. The Java compilers convert your code from
human readable Java source files to something called “bytecode” in the Java world. These are interpreted by a Java
Virtual Machine, which operates much like a physical CPU might operate on machine code, to actually execute the
compiled code. Although it might seem like this is inefficient, much effort has been put into making this process
very fast and efficient. These efforts have paid off in that Java performance in generally second only to C/C++ in
common language performance comparisons.
Android applications run in a special virtual machine called the Dalvik VM. While the details of this VM are
unimportant to the average developer, it can be helpful to think of the Dalvik VM as a bubble in which your
Android application runs, allowing you to not have to worry about whether the device is a Motorola Droid, an HTC
Evo, or the latest toaster running Android. You don’t care so long as the device is Dalvik VM friendly—and that’s
the device manufacturer’s job to implement, not yours.
Why is Java Secure?
Let’s take this bubble idea a bit further. Because Java applications run within the bubble that is a virtual machine,
they are isolated from the underlying device hardware. Therefore, a virtual machine can encapsulate, contain, and
manage code execution in a safe manner compared to languages that operate in machine code directly. The
Android platform takes things a step further. Each Android application runs on the (Linux-based) operating system
using a different user account and in its own instance of the Dalvik VM. Android applications are closely
monitored by the operating system and shut down if they don’t play nice (e.g. use too much processing power,
become unresponsive, waste resources, etc.). Therefore, it’s important to develop applications that are stable and
responsive. Applications can communicate with one another using well-defined protocols.
Compiling Your Code
Like many languages, Java is still a compiled language even though it doesn’t compile all the way down to
machine code. This means you, the developer, need to compile your Android projects and package them up to
deploy onto devices. The Eclipse development environment (used with the Android Development plug-in) makes
this pretty painless. In Eclipse, automatic compilation is often turned on by default. This means that every time you
save a project file, Eclipse recompiles the changes for your application package. You immediately see compile
errors. Eclipse also interprets Java as you type, providing handy code coloring and formatting as well as showing
many types of errors as you go. Often, you can click on the error and have Eclipse automatically fix a typo, or add
an import statement, or provide a method stub for you, saving lots of typing.
You can still manually compile your code if you so desire. Within Eclipse, you’ll find the Build settings under the
project menu. If you have “Build Automatically” turned on, you can still choose the “Clean…” option that will
allow you to do full rebuild of all files. If “Build Automatically” is turned off, “Build All” and “Build Project”
menu options are enabled. “Build All” means to build all of the projects in the workspace. You can have many
projects in an Eclipse workspace.
The build process, for regular Java projects, results in a file with the extension of JAR – Java ARchive. Android
applications take JAR files and package them for deployment on devices as Android PacKage files with an
extension .apk. These formats not only include your compiled Java code, but also any other resources, such as
strings, images, or sound files, that your application requires to run as well as the Application Manifest file,
AndroidManifest.xml. The Android Manifest file is a file required by all Android applications, which you use to
define configuration details about your app.
What is an Object Oriented Programming Language?
Okay. Time for a very brief and 20,000 foot view of object oriented programming (OOP). OOP is a programming
style or technique that relies upon the definition of data structures called objects. For those new to OOP, an object
can be thought of much like a custom data type. For example, you might have a Dog object, which represents the
blueprint for a generic dog, with a name, breed, and gender. You could then create different instances of the Dog
object to represent specific dogs. Each Dog object must be created by calling its constructor (a method that has the
same name as the object itself, and may or may not have parameters for setting initial values). For example, the
following Dog objects use a constructor with three parameters (name, breed, gender):
Dog dog1 = new Dog("Lassie", collie, female);
Dog dog2 = new Dog("Fifi", poodle, female);
Dog dog3 = new Dog("Asta", foxterrier, male);
So where is this Dog object defined? Well, here we need to begin defining some of the fundamental building
blocks of the Java programming language. A class provides a definition for an object. Therefore, there is a Dog
class somewhere—either defined by you or in some library somewhere. Generally speaking, a class will be defined
in its own file, with the filename matching the class name (e.g. Dog.java). There are exceptions to this rule, such as
classes defined within other classes (when a class is declared within a class, it is generally defined for use within
the parent class only as a helper class, and referred to as an inner class).
When you want to reference an object from within another class, you need to include an import statement in the top
of your class file, much like you would use a #include statement in a compiled language like C.
A class typically describes the data and behavior of an object. The behavior is defined using class methods. Method
is the common term for a subroutine in an OOP language. Many common object classes are defined in shared class
libraries like software development kits (SDKs), whereas others are defined by you, the developer, for your own
purposes. Software is then built up by using and manipulating object instances in different ways.
Please realize this is a very generalized definition of OOP. There are entire books written on this subject. If you’d
like to know more about OOP, here are a few resources you might want to check out:
• Wikipedia has a nice overview of OOP
• Sun Java Tutorials on Java
• The Java Tutorials at Oracle
Note: We use a lot of different terminology in this tutorial. There are multiple ways to refer to a given concept (e.g.
superclass vs. parent class), which is confusing to those new to object oriented programming. Different developers
use different terms, and so we have tried to mention synonyms where appropriate. Deciding which terms you will
use is a personal choice.
Understanding Inheritance
Here is another important Java concept you’ll run into a lot: inheritance. Simply put, inheritance means that Java
classes (and therefore objects) can be organized into hierarchies with lower, more specific, classes in the hierarchy
inheriting behavior and traits from higher, more generic, classes.
This concept is best illustrated by example. Let’s pretend we are developing a Java application to simulate an
aquarium. This aquarium has some fish in it. Therefore, we might define a class to represent a fish. This class,
called Fish, could include some data fields (also called attributes, or class member variables) to describe a fish
object: species, color and size; as well as some of its behavior in the form of methods (also called subroutines, or
functions in procedural languages), like eat(), sleep(), and makeBabyFish().
A special type of method, called a constructor, is used to create and initialize an object; constructors are named the
same as their class and may include parameters. The following Fish class has two constructors: one for creating a
generic Fish object and another for constructing a specific Fish object with some initial data. You’ll also see that
the Fish class has two eat() methods: one for eating something random, and another for eating another fish, which
would be represented by another instance of the Fish class:
public class Fish {
Fish() {
// generic fish
mSpecies = "unknown";
mColor = "unknown";
mSize = 0;
}
Fish(String species, String color, int size) {
mSpecies = species;
mColor = color;
mSize = size;
}
public void eat() {
// eat some algae
};
public SillySensor()
{
sensorData=0;
}
return sensorData;
}
}
Conditionals
Java includes conditional statements, which can be used to execute snippets of code if, and only if, certain
conditions are met. Typically, a conditional statement involves two sides. If the two sides are equivalent, the
statement is true, otherwise it is false.
Java has all the typical conditional operators, such as:
• == equal to, as in (a == b)
• != not equal to, as in (x != y)
• > greater than, as in (z > y)
• >= greater than or equal to, as in (q >= z)
• < less than, as in (b < a)
• <= less than or equal to, as in (a <= z)
And when you need to combine multiple conditional statements into a single larger conditional test, you can use
AND (&&) and OR (||):
• ((a==b)&& (a==c)) // true only if A is equal to B and equal to C
• ((a==b) || (a==c)) // true only if A is equal to B or equal to C
Java has bitwise operators (&, |, ^), shifts (>>, <<), and complement (~) operators as well, should you need them.
See the Java documentation for more details.
Now that you know how to craft a conditional statement, you can create conditional code segments. The simplest
form of a conditional code statement is the if() statement:
boolean condition = true;
if(condition==true)
{
// Execute this code only if condition variable is true
}
If you want to provide alternative code to run if the condition is not met, then use the else clause with the if()
statement:
boolean condition = true;
if(condition==true)
{
// Execute this code only if condition variable value is true
} else {
// Execute this code only if condition variable value is false
}
If you want to handle more than two cases, you can use cascading if-else-if-else statements, like this:
if(iVar==0) {
// variable is zero
} else if (iVar > 0) {
// variable is a positive number
} else {
// variable is a negative number
}
Switch Case Statements
When you have a number of different code paths possible that branch from a single variable value, you can use a
switch() statement. With a switch statement, you supply the variable to check for and provide numerous options to
execute for specific cases. You can also supply a default option to execute if none other cases apply. Each case can
be terminated with a break statement. If a break statement is not supplied, the code will continue executing into the
next case statement.
char singleChar = 'z';
switch(singleChar) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
// singleChar is a vowel! Execute this code!
break;
default:
// singleChar is a consonant! Execute this code instead!
break;
}
Loops
When you want to execute code repeatedly, or using recursion (heh, look that one up if you don’t know what we’re
talking about), Java has support for several different kinds of loops.
To loop continuously provided that a statement is true, use a while() loop:
int numItemsToProcess = 3;
while(numItemsToProcess > 0)
{
// process an item
numItemsToProcess--;
}
If you want to evaluate the conditional loop expression AFTER the first iteration, you can use a do-while loop
instead:
do
{
// check for items to process, update numItemsToProcess as required
// process item, updated numItemsToProcess
} while (numItemsToProcess > 0);
Finally, if you want to loop for a specific number of iterations, you can use a for() loop. A for() loop has three
parameters: the initial value, the terminating value, and the incrementing value. For example, to execute a loop 100
times, printing the numbers 1 through 100, you could use the following for() loop:
for(int i = 1; i <=100; i++)
{
// print i
}
Note: You can also use a break statement to get out of a while(), do-while() or for() loop when necessary. You can
also use a continue statement to skip the rest of a current iteration of a loop and move on to the next iteration
(reevaluating the conditional expression, of course).
Passing By Value vs. By Reference
There are no pointers in Java. Ok, ok, go ahead and breathe a sigh of relief. Life is hard enough without pointers
mucking things up, right?
Ok, now it’s time to pay attention again. In Java, method parameters are passed by value. However, when a method
parameter is an object (that is, anything except a primitive type), only a reference to that object is passed into the
method [much like pointers, sorry!]. Therefore, in order to modify the object passed into a given method, you
generally pass in the object reference, and then act upon it, which modifies the underlying data of the object you
passed in. You cannot, however, swap out the object itself… Here’s a quick example:
Here, we have a class called Cat:
public class Cat {
private String mCatName;
Cat(String name) {
mCatName=name;
}
Cat haveKitten()
{
Cat kitten = new Cat("Luke");
return kitten;
}
Finally, let’s call these methods and see how they act upon Cat object instances:
Cat cat1 = new Cat("Jabba");
Cat cat2 = new Cat("Leia");
} catch (ClassNotFoundException e) {
// Class not found!
} catch (Exception e) {
// Unknown exception
}
The class (in this case, NotificationManager) need not have the corresponding import statement in your code; you
are not compiling in this class into your application. Instead, the class loader will load the class dynamically at
runtime, if possible. You can then inspect this Class object and use the reflection techniques described in the rest of
this tutorial.
Inspecting the Constructors Available Within a Class
You can inspect the constructors available within a given Class. To get just the constructors that are publicly
available, use getConstructors(). However, if you want to inspect those methods specifically declared within the
class, whether they are public or not, use getDeclaredConstructors() instead. Both methods return an array of
Constructor (java.lang.reflect.Constructor) objects.
For example, the following code iterates through the declared constructors of a class:
Constructor[] aClassConstructors = classToInvestigate.getDeclaredConstructors();
for(Constructor c : aClassConstructors){
// Found a constructor c
}
Once you have a valid Constructor object, you can inspect its parameters and even declare a new instance of the
class using that constructor with the newInstance() method.
Inspecting the Fields Available Within a Class
You can inspect the fields (or attributes) available within a given Class. To get just the methods that are publicly
available, including inherited fields, use getFields(). However, if you want to inspect those fields specifically
declared within the class (and not inherited ones), whether they are public or not, use getDeclaredFields() instead.
Both methods return an array of Field (java.lang.reflect.Field) objects.
For example, the following code iterates through the declared fields of a class:
Field[] aClassFields = classToInvestigate.getDeclaredFields();
for(Field f : aClassFields){
// Found a field f
}
You can also check for a specific public field by name using the getField() method. For example, to check for the
EXTRA_CHANGED_PACKAGE_LIST field of the Intent class (which was added in API Level 8, or Android
2.2), you could use:
String sClassName = "android.content.Intent";
try {
Class classToInvestigate = Class.forName(sClassName);
String strNewFieldName = "EXTRA_CHANGED_PACKAGE_LIST";
Field newIn22 = classToInvestigate.getField(strNewFieldName);
} catch (ClassNotFoundException e) {
// Class not found
} catch (NoSuchFieldException e) {
// Field does not exist, likely we are on Android 2.1 or older
// provide alternative functionality to support older devices
} catch (SecurityException e) {
// Access denied!
} catch (Exception e) {
// Unknown exception }
Once you have a valid Field object, you can get its name using the toGenericString() method. If you have the
appropriate permissions, you can also access the value of that class field using the appropriate get() and set()
methods.
Inspecting the Methods Available Within a Class
You can inspect the methods available within a given Class. To get just the methods that are publicly available,
including inherited methods, use getMethods(). However, if you want to inspect those methods specifically
declared within the class (without inherited ones), whether they are public or not, use getDeclaredMethods()
instead. Both methods return an array of Method (java.lang.reflect.Method) objects.
For example, the following code iterates through the declared methods of a class:
Method[] aClassMethods = classToInvestigate.getDeclaredMethods();
for(Method m : aClassMethods)
{
// Found a method m
}
Once you have a valid Method object, you can get its name using the toGenericString() method. You can also
examine the parameters used by the method and the exceptions it can throw. Finally, if you have the appropriate
permissions, you can also call the method using the invoke() method.
Inspecting Inner Classes
You can inspect the inner classes defined within a Class using getDeclaredClasses() method. This method will
return an array of Class (java.lang.class) objects declared within the parent class. These classes can then be
inspected like any other.
Inspecting Member Modifiers
You can also inspect the flags and security settings—called modifiers—associated with a given Class, Field, or
Method using the getModifiers() method. Interesting modifiers include whether the component is public, private,
protected, abstract, final, or static (amongst others).
For example, the following code checks the security modifiers of a class:
int permissions = classToInvestigate.getModifiers();
if(Modifier.isPublic(permissions)) {
// Class is Public
}
if(Modifier.isProtected(permissions)) {
// Class is Protected
}
if(Modifier.isPrivate(permissions)) {
// Class is Private
}
Keep in mind that you cannot dynamically access or invoke any class, method, or field using reflection that you
would not normally be able to access at compile-time. In other words, regular class security is still applied at
runtime.
Inspecting Class Metadata
You can also inspect the metadata—called annotations—associated with a given class, field or method using the
getAnnotations() method. Interesting metadata associated with a class might include information about
deprecation, warnings, and overrides, among other things.
For example, the following code checks the metadata available for the AbsoluteLayout class. Since this class was
deprecated in Android 1.5, one of the annotations returned is @java.lang.Deprecated() when this code is run on
Android 2.2:
String sClassName = "android.widget.AbsoluteLayout";
try {
Class classToInvestigate = Class.forName(sClassName);
} catch (ClassNotFoundException e) {
// Class not found!
} catch (Exception e) {
// Handle unknown exception!
}
Similarly, you could simply check for the existence of a specific annotation, such as deprecation, by its type:
if(classToInvestigate.isAnnotationPresent(java.lang.Deprecated.class) == true)
{
// Class is deprecated!
}
Reflection: Handy for Debugging
You can also use reflection to assist with debugging. For example, you might want to use the class keyword to
access the underlying class data for a given type:
import android.app.Activity;
…
String strClassName = Activity.class.getName(); // android.app.Activity
You can also get class information from a variable instance using the getClass() method of the Object class (which
is therefore inherited by all classes in Java):
String silly = "Silly String!";
Class someKindOfClass = silly.getClass();
String strSillyClassName = someKindOfClass.getName(); // java.lang.String
If you want to check the class of a variable, using instanceof is more appropriate. See the previous tutorial on
instanceof for more details.
Similarly, you might want to use the getClass() method with the this keyword to check the name of the class you’re
currently in and include this information as part of your debug logging to LogCat:
String strCurrentClass = this.getClass().getName(); // e.g. the current Activity
Log.v(strCurrentClass, "Debug tag is current class.");
Why Not To Use Reflection
As you’ve seen, reflection can be used to great effect, especially when you are unsure if a specific class or method
is available at compile time. Reflection does, however, have some drawbacks, including reduced performance and
the loss of the strong typing and safe coding practices enforced at compile time. It’s best to use reflection
sparingly, but do use it when needed.
Wrapping Up
Reflection is a powerful tool that Java developers can use to explore packages and APIs programmatically at
runtime. While reflection operations come at a cost, they give the developer the flexibility that is sometimes
essential for getting the job done. Android developers frequently use these simple reflection techniques to test for
the availability of specific classes, interfaces, methods, and fields at runtime, enabling them to support different
versions.
you’ve read about how iteration works in Java. Test your new skills with this challenge: five progressively difficult
exercises that help you solidify your knowledge of the Java programming language and Android development.
That’s right, Android too! You may need to refer to other Android tutorials that we’ve published on Mobiletuts+,
but if you can complete this challenge successfully you will know you are progressing nicely in your Java and
Android SDK understanding.
Setup
To prepare for this challenge, you’ll want to start with a basic Android application. Simply create an Android
application within Eclipse and edit its default Activity, specifically the onCreate() method, to test the code from
each of these challenges.
If what we’ve just asked of you is already too challenging, we would recommend taking a step back. Start with
some of the Android tutorials, such as Introduction to Android Development or Beginning Android: Getting
Started with Fortune Crunch. Once you’ve mastered setting up an Android project, return and try these exercises.
Getting Started: Working with String Array Resources
At first, we considered using a simple string array for you to use to complete these iteration challenges:
String aColors[] = {"Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet"};
However, there’s a much better way to store fixed arrays of values in Android: as resources. To create a string
array resource, you must first create String resources for each value. Next, create a String Array resource using
those String resources as elements. Use the <string-array> tag to combine String resources into an array resource
using child <item> tags for each element. For instance, here’s an array of colors inside an Android resource file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="red">Red</string>
<string name="orange">Orange</string>
<string name="yellow">Yellow</string>
<string name="green">Green</string>
<string name="blue">Blue</string>
<string name="indigo">Indigo</string>
<string name="violet">Violet</string>
<string-array name="colorsArray">
<item>@string/red</item>
<item>@string/orange</item>
<item>@string/yellow</item>
<item>@string/green</item>
<item>@string/blue</item>
<item>@string/indigo</item>
<item>@string/violet</item>
</string-array>
</resources>
To load this array resource in your Activity class, use the getStringArray() method of the Resources object. For
instance:
String aColors[] = getResources().getStringArray(R.array.colorsArray);
Challenge #1: Warm-Up Challenge
Now you’re ready to get started. Load the string array from the resources, as discussed above. Then, iterate through
the array’s contents using a for() loop. Print each string to the Android LogCat debug log using the Log.v()
method.
Find the answer to this challenge in the challengeOne() method of the downloadable project.
Challenge #2: Stretch Your Skills
Iterate the same array as Challenge #1, but use a different iteration mechanism. For example, use a while() loop
instead. Print each string to the Android LogCat debug log using the Log.v() method.
Find the answer to this challenge in the challengeTwo() method of the downloadable project.
Challenge #3: Reverse!
Iterate the same array backwards. Print each string to the Android LogCat debug log using the Log.v() method.
HINT: Challenge #2 can help.
Find the answer to this challenge in the challengeThree() method of the downloadable project.
Challenge #4: It’s All About Character
Next, go back to the for() loop you created in Challenge #1. Update it to print out the individual characters of each
String as well. This challenge will require an inner for() loop.
HINT: You can use the toCharArray() method of the String class to retrieve a character array.
The answer to this challenge is in the challengeFour() method of the downloadable project.
Challenge #5: Reflect on How Far You’ve Come
For this final challenge, you’re going to need a bit of understanding about Java reflection. Use reflection to iterate
through the declared fields within the android.os.Build class using a for() loop. Print each field name to the
Android LogCat debug log using the Log.v() method.
HINT: Our short tutorial on Java reflection will teach you everything you need to know to complete this challenge.
We’ve provided two different solutions for this challenge. The first solution assumes that the package is imported
and the compiler knows about the class. The second solution does not make this assumption. These solutions are
found in the challengeFiveA() and challengeFiveB() methods of the downloadable project.
Conclusion
Android developers use iteration techniques on a regular basis to solve coding problems. Iteration is frequently
used to iterate arrays, data structures like lists, or database content using cursors. Feel free to post your alternative
answers (or any questions) in the comments section.
In this tutorial, you’ll become familiar with the concept of inner classes in Java—those classes whose scope and
definition are encompassed within another class. You’ll also learn about anonymous inner classes, which are used
quite frequently when developing with the Android SDK.
Android applications are written in the Java, an object-oriented programming language. In this tutorial, you’ll learn
about inner classes, when and why to use them and how they work. You’ll also learn how to create new objects
dynamically using anonymous inner classes.
What You’ll Need
Technically, you don’t need any tools to complete this tutorial but you will certainly need them to develop Android
applications.
To develop Android applications (or any Java applications, for that matter), you need a development environment
to write and build applications. Eclipse is a very popular development environment (IDE) for Java and the
preferred IDE for Android development. It’s freely available for Windows, Mac, and Linux operating systems.
What is an Inner Class?
Most classes in Java are top-level classes. These classes, and the objects they define, are stand-alone. You can also
create nested classes in order to clearly encapsulate and define subordinate objects that only matter in the context
of the outer class. Nested classes are called inner classes.
Inner classes can have all the features of a regular class, but their scope is limited. Inner classes have another
benefit: they have full access to the class in which they are nested—this feature makes inner classes perfect for
implementing adapter functionality like iterators.
Here’s an example of a top-level class with two inner classes:
public class User {
class LoginInfo
{
// Login info fields
// Login/Logout methods
// Can access User fields/methods
}
class Preferences
{
// User preference fields
// Get/Set preference methods
// Reset preferences method
// Can access User fields/methods
}
}
In this example, the User class has two inner classes: LoginInfo and Preferences. While all user-related data and
functionality could be defined in the User class, using the inner classes to compartmentalize functionality can make
code easier to read and maintain. The inner classes LoginInfo and Preferences also have access to the
protected/private fields and methods available within the User class, which they might not otherwise have due to
security, if they were defined as stand-alone classes themselves.
It’s important to remember, though, that inner classes really only exist to help the developer organize code; the
compiler treats inner classes just like any other class, except that the inner classes have a limited scope, and are
therefore tethered to the class they are defined with. Said another way, you would not be able to use or instantiate
the LoginInfo or Preferences classes except with an instance of the User class, but the inner classes could access
any fields or methods available in the outer class User, as needed.
Using Static Nested Classes
One particularly use for nested classes is static nested classes. A static inner class defines behavior that is not tied
to a specific object instance, but applies across all instances. For example, we could add a third nested class, this
time static, to the User class to control server-related functionality:
public class User {
class LoginInfo {}
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
}
}
The log output for the button click proceeds as follows:
10:24 18:18:53.075: VERBOSE/MyLoggingTag(751): this Class name: com.androidbook.classchaos.ClassChaosActivity$1
What is Javadoc?
Javadoc is a utility provided with the Java SDK that allows developers to generate code documentation from Java
source files. Development environments like Eclipse have built-in support for Javadoc and can generate searchable
HTML reference materials from Javadoc-style comments. In fact, the Android SDK reference is a form of Javadoc
documentation.
Android applications are written in the Java, a programming language. Java has a number of primitive data types
for different kinds of numbers (integers, floats, etc.), Boolean values, and single characters. In addition to storing
textual data as arrays or characters, Java also includes a powerful object class called String (java.lang.String),
which encapsulates textual data neatly and can be used to manipulate content. In this tutorial, you’ll learn how to
create, use and manipulate strings in different ways, including how to store them as Android project resources.
What You’ll Need
Technically, you don’t need any tools to complete this tutorial but you will certainly need them to develop Android
applications.
To develop Android applications (or any Java applications, for that matter), you need a development environment
to write and build applications. Eclipse is a very popular development environment (IDE) for Java and the
preferred IDE for Android development. It’s freely available for Windows, Mac, and Linux operating systems.
For complete instructions on how to install Eclipse (including which versions are supported) and the Android SDK,
see the Android developer website.
What is a String?
At the most fundamental level, Java programs are broken into functionality and data. Much human-readable data
comes in the forms of words, characters, punctuation, numbers and so on. Basically, anything the user can type on
a keyboard. Programmers call this storage of textual content “string data”, but the data itself can be stored using a
variety of different data structures, depending on your requirements:
• The Java String class (java.lang.String) is a utility class for storing string data that will not be modified.
• The Java StringBuilder class (java.lang.StringBuilder) is a utility class for storing string data that will be
modified; used when concurrency is not an issue.
• The Java StringBuffer class (java.lang.StringBuffer) is a utility class for storing string data that will be
modified; used when concurrency is an issue.
• An array of char primitives or Character (java.lang.Character) variables
• An array of byte primitives or Byte (java.lang.Byte) variables
• Various other data structures and object classes can be used to store string data
As you can see, there are numerous ways to store string data in Java. For example, the following Java variables
represent a string of vowel characters in different ways (as bytes, characters, Unicode representations or sub-
strings):
String strVowels = "aeiou";
char astrVowels[] = { 'a', 'e', 'i', 'o', 'u' };
byte abyteVowels[] = { 'a', 'e', 'i', 'o', 'u' };
byte abyteVowelsU[] = { '\u0061', '\u0065','\u0069','\u006F','\u0075' };
String uVowels = new String("\u0061\u0065\u0069\u006F\u0075");
CharSequence csVowels = (CharSequence) new String("aeiou");
StringBuffer sbVowels = new StringBuffer("a" + "e" + "iou");
StringBuilder sVowelBuilder = new StringBuilder();
sVowelBuilder.append('a');
sVowelBuilder.append("eio");
sVowelBuilder.append('\u0075');
The String class is the convenience class used most often, especially by beginners. You’ll also want to have a
passing understanding of the CharSequence (java.lang.CharSequence) interface, as it is often used when working
with Android resources.
Working with the String Class
The String class is available as part of the java.lang package, which is included within the Android SDK for
developers to use.
The String class represents an immutable (unchangeable) sequence of Unicode (16-bit encoding) characters,
appropriate for storing characters in any language (English, German, Japanese, and so on).
So what does this have to do with Android development? Well, strings are used to store content displayed on
application screens, or to store the input taken in from a user. Android developers are constantly loading, creating,
and manipulating string data. So let’s look at some of the stuff we can do with the String class.
Creating Strings
The String class has numerous constructors, for creating and instantiating string variables. String variables can be
set to empty using the null keyword. You can also set its content from byte, character, or other String data. For
example, here are some ways to create String variables for use within your applications (some are initialized from
the variables, like uVowels and sVowelBuilder, defined earlier in this tutorial):
String strVowels1 = "aeiou";
String strVowels2 = new String("aeiou");
String strVowels3 = new String(sVowelBuilder);
String strVowels4 = new String(sbVowels);
String strVowels5 = new String(uVowels);
String strVowels6 = new String(abyteVowels2);
String strVowels7 = new String(abyteVowelsU);
String strVowels8 = new String("a" + "e" + "iou");
String strVowels9 = new String( new char[]{'\u0061',
'\u0065','\u0069','\u006F','\u0075'});
String strVowels10 = new String(new byte[]{ '\u0061',
'\u0065','\u0069','\u006F','\u0075' });
Android applications are written in the Java, a programming language. Java has a number of primitive data types
for different kinds of numbers (integers, floats, etc.), Boolean values, and single characters. Java also includes
numerous classes for storing, formatting and modifying date and time data for use within your Android
applications. In this tutorial, you’ll learn how to determine the current date and time, store date and time data and
display it in a number of ways.
What You’ll Need
Technically, you don’t need any tools to complete this tutorial but you will certainly need them to develop Android
applications.
To develop Android applications (or any Java applications, for that matter), you need a development environment
to write and build applications. Eclipse is a very popular development environment (IDE) for Java and the
preferred IDE for Android development. It’s freely available for Windows, Mac, and Linux operating systems.
What is a Date or Time, Really?
First things first: the date and the time are basically two parts of the same piece of data (a point in time). When it
comes to storing dates and times in a computer, it can be helpful to think back to your first computer class and
recall that all data on a computer is made up of “ones and zeros”. Computers (and Android devices are no
exception) do not really have a sense of time like people do, but instead keep a numeric representation of the
current date or time (always ticking forward, one millisecond at a time) and then format this information in
different ways to suit specific purposes. After all, a single instant in time is interpreted differently depending upon
your time zone or location, whether or not you (or your area) recognize daylight savings, and various other factors.
Add to this fact that dates and times are displayed differently in different cultures and locales. For example, in the
United States, we often format our dates like this: April 6th, 1981, or 04/06/1981 whereas in Europe, the day
normally precedes the month, like this: 6 April, 1981, or 06/04/1981. Similarly, some countries have the concept of
AM and PM with a 12-hour, whereas others simply use a 24-hour clock.
Computers, including Android devices, calculate times and dates as a single number (a long)—which grows as
time passes. The number itself equates to the number of milliseconds elapsed since a specific date in the past. In
this case, the point in time at which the “time” started ticking is: midnight, January 1, 1970. This mechanism is
referred to as Unix time, or POSIX time.
What’s a Developer to Do?
Pop quiz! Which of the following strings correctly represents the 4th month of the (Gregorian) calendar year: A,
April, APR, Apr, 4, or 04? The answer? All of them. Already, working with dates and times seems a bit
complicated, doesn’t it? In fact, we did a quick perusal of all the Java reference books in our office (not
insubstantial) and very few cover dates and times in any substantial way. But don’t panic. Just accept the fact that,
as a developer, you will have to expend a bit of effort towards satisfying two goals:
1. Your External Goal: To allow the user to work with the date and time formats they are most comfortable with, or
at least familiar with.
2. Your Internal Goal: To keep your application code format-independent, so it works everywhere with little
hassle.
Now let’s talk a bit about each of these goals.
The External Goal: Be Flexible & Use Standard Controls
Have you ever noticed that few travel websites let the user manually enter date or time information? Instead, they
rely upon calendar pickers and fixed day, month and year dropdowns, or, at minimum, enforce a specific date
format (usually tied to your language/country, which they ask for in advance). From a user interface perspective,
your apps should honor date and time nuances, at least to some extent. However, you should also carefully
consider the methods in which the user can enter date and time information. By using standard date and time
pickers in your Android apps, such as DatePicker and TimePicker, you effectively limit the data users can input to
that which can be easily converted into appropriate date and time structures, without having to parse every known
format (not to mention its typos).
You’ll find these little code tidbits—which we are calling Java shorthand—used in the Android SDK sample code,
and just about every Android development book published at this time, not to mention online tutorials and
developer forums. None of these tips are Android-specific; they are simply Java techniques that routinely confound
beginners new to Java and Android, based upon the emails we receive from our readers.
Tip #1:Java’s Unary Operators (Increment/Decrement Variable
Shorthand)
Many developers like their code short and easy to read. Like some other programming languages, Java includes
unary operators for easily incrementing and decrementing variable values by 1.
In other words,
int counter = 1;
counter++;
counter--;
This code is equivalent to:
int counter = 1;
counter = counter + 1;
counter = counter – 1;
These unary operators can appear before (prefix) or after (postfix) the variable. The location of the operator
dictates whether the increment/decrement operation happens before or after the rest of the expression is evaluated.
For example, the following code shows how unary operators work by manipulating a variable called counter using
Android logging:
int counter = 0;
Log.i(DEBUG_TAG, "The counter value is ="+counter++); // prints 0
Log.i(DEBUG_TAG, "The counter value is ="+counter); // prints 1
Log.i(DEBUG_TAG, "The counter value is ="+counter--); // prints 1
Log.i(DEBUG_TAG, "The counter value is ="+counter); // prints 0
Log.i(DEBUG_TAG, "The counter value is ="+(++counter)); // prints 1
Log.i(DEBUG_TAG, "The counter value is ="+--counter); // prints 0
Among the most important views in this perspective is the Package Explorer view, by default located on the left
hand column of the workbench. This view is an overview of your entire project. It also shows the states of
individual files with regard to compile issues, version control, etc.
Another important view in the Java perspective is the Problems view, by default located in the bottom center panel
of the workbench. This is where you will find compile warnings and errors listed. You can double-click an item to
be taken directly to the error in the Java or XML file.
The DDMS Perspective
DDMS is short for Dalvik Debug Monitor Server, which communicates with the low-level services of a device or
emulator. Switch to the DDMS perspective now by selecting Window > Open Perspective > DDMS.
The Devices view, located in the left column of the workbench, is where you will see any Android devices
available to your computer. This includes both phones attached to your machine and running emulators. Under
each device, you will see all the running processes. There are toolbar buttons on the view for launching the
debugger on a process, getting information about heaps and threads, stopping processes, and taking screenshots.
The Emulator Control view, also in the left column, lets you do the following:
• Set the status of the voice connection.
• Set the status, speed and latency of the data connection.
• Simulate an incoming call or SMS from a supplied phone number.
• Provide a simulated set of points for the GPS via a latitude/longitude point, or GPX/KML file.
Using the File Explorer view, accessible as a tab at the top-right of the center column, you can browse the
file system of a device. For an emulator or a rooted phone, you will have access to the private directories
/data and /system. For non-rooted phones, you will only have access to /sdcard.
The Debugging Perspective
The debugging perspective will provide in-depth information about your applications. Switch to the
debugging perspective now by selecting Window > Open Perspective > Debug.
The Debug view will show you the running apps being analyzed, and, when stopped on a breakpoint or
exception, the call stack of the application as well. The Variables view displays the contents of any local
variables at the current breakpoint.
The LogCat view in the lower right hand corner displays all logging output using the android.util.Log class.
You can filter based on tags, or different log levels such as debug, information, error, etc.
Your First Application
To begin creating an Android application, switch back to the Java perspective and select File > Menu >
Android Project. Doing so will launch the application creation wizard, and you will be prompted to enter
meta-information about your project in three categories: Contents, Build Target, and Properties.
Name the application “DemoApp” and leave the Contents section with all the default values.
The Build Target section defines the version of the SDK that our demo app will be compiled against. For
this tutorial, choose API level 4 (Android 1.6) because it will run on a wide range of hardware and the API
will allow us to handle different screen resolutions.
Next is the Properties section, which provides the wizard with more information about what classes
to generate and what they should be named. The Application Name setting will be displayed under the
application icon, as well as the application’s title bar when launched. The Package name provides the base
Java namespace for your generated classes. In order to create a default activity, make sure Create Activity
is checked and provide an activity name. The last option is the Min SDK version. This value determines
what version of Android needs to be on a phone in order for this application to be installable. This is
generally set to the same API level that you chose under Build Target.
Once you enter all this information and click Finish, you will have a basic “Hello World” application that is
almost ready to run on a phone or an emulator. Before we setup an emulator and run the application, take a
few minutes to examine the standard template content generated:
The AndroidManifest.xml file
The AndroidManifest.xml file provides metadata about your application that the Android OS will need to
run the app properly. The name of the application, used for both the app icon and the activity titlebar, and
the app icon are defined under Application Attributes. You will notice that the Name field doesn’t actually
contain the name text, but “@string/app_name” instead. This is a string reference and can be used anytime
a string is expected. The actual string text is then defined in one of the XML files found under the
res/values folder. The app creation wizard generated a file there called strings.xml.
The Application Nodes section is where all the activities are defined for the application. Our app’s single
activity is called MainActivity and listed here.
The /res folder
The res folder is where most application resources are stored. The main content categories include
drawables, layouts, and values.
Drawables are generally bitmaps images in the form of .PNGs. Drawables can also be nine-patch images,
which are .PNGs with special data in the image that help Android do a better job when stretching the
image. Nine-patch images can be created with the nine-patch tools in the SDK, or with an image creation
tool like Photoshop.
Layouts are where you define your screens. To view the XML for the layout on screen, click the main.xml
tab.
Values are where you define (in XML) your globally used colors, dimensions, strings and styles. The
strings.xml file allows you to add and edit values for your project.
The /gen folder
This is where code is generated for all the resources defined in your res folder. This is how you can access
layouts and controls defined within your code.
The /src folder
The src folder contains all of your custom source code, grouped into packages. Packages are simply there to
help categorize your source code into logical (and manageable) groups.
The /assets folder
The assets folder is a place to store miscellaneous files you need to access in your code as raw data. All
files in the res folder have methods to load the specific types, whereas the only way to load something from
assets is to programmatically open it as a file.
Creating an Android Virtual Device
Virtual devices make it possible to run and test your code without owning an actual Android phone. Since
there are several different version of the OS you can target, you will eventually need to create multiple
versions of virtual devices, but for now, we’ll create one using API level 4 (1.6). You can do this via the
AVD Manager. From the main toolbar, select Window > Android SDK and AVD Manager.
Once you’ve opened the manager and are viewing your list of virtual devices, click the “New” button to
create your virtual device.
I generally name my virtual devices using the OS version number along with the preset resolution that I
choose, so in this case, 1.6-hvga. It’s good to also create an SD Card for the emulator which I usually set to
16MB, unless I know I will need more space. Click the Create AVD button, and you will see your device
listed.
Go ahead and start the virtual device by selecting it and clicking the “Start” button.
Running & Debugging Your First App
Eclipse, along with the Android Developer Tools, offers a great environment for debugging applications.
For debugging, you’ll use both the Debugging and the DDMS perspectives. The debugging perspective will
be used for stepping through code, viewing values of variables, and setting breakpoints. The DDMS
perspective will be used to control the emulator, view threads, and view memory allocation.
Since this is our first time running the application, we need to create something called a run configuration.
Run configurations are the settings that Eclipse will use to run (or debug) your application. Each
application can have multiple configurations. One might be set up to always deploy and run on an attached
phone, and another could be setup to only run in a specific emulator instance. At this point, disconnect your
phone if you happened to have it attached to your machine so you can see the app run on the emulator first.
To create the run configuration, select DemoApp in the Package Explorer, then choose Run > Run from
the main menu. In the next dialog, choose Android Application and click OK. The emulator that we created
earlier should launch. When the emulator first starts up, it may appear with the lock screen; just click menu
to be taken to your new app. You should now see the text “Hello World” on screen!
Our next step will be to set a breakpoint. Open the MainActivity.java file by double-clicking it in the
Package Explorer. It is located under /src > com.demo.demoapp. Next, on the line that contains:
view plaincopy to clipboardprint?
1. "super.onCreate(savedInstanceState)"
double-click in the gray column to the left of the line (where you see the blue circle in the screenshot
below). If you were successful, there should now be a blue circle indicating the breakpoint.
Now switch to the debugging perspective by selecting Window > Open Perspective > Debug . To debug
the application, select Run > Debug.
In the Debug view, you should see a list of items under DalvikVM/Thread. This is the call stack since we
are now stopped at the breakpoint we set earlier. The Variables view will show all local variables at the
current breakpoint. You can expand the item “this” to see all the values of our MainActivity instance.
Finally, LogCat will display all logging information coming from the emulator.
To continue running the app, you can use the toolbar on the Debug view (as seen in the screenshot above),
or choose the same actions from the run menu. Choose Run > Resume to let the app continue running.
Conclusion
This tutorial took you through the various parts of Eclipse and ADT that you need to be familiar with to
begin Android development. Although we didn’t cover the details of the application source code, it is
important to start with a strong understanding of the tools you will use every day during development. In
coming articles, we will continue to dig deeper into writing progressively complex applications and
creating a compelling UI.