Java For Android

Java for Android is subtly different to vanilla Java. Learn about the differences and what they mean for your code in this Java for Android article. By Darryl Bayliss.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 4 of this article. Click here to view the first page.

Not-So-Paranormal Activity

The Activity class is an object dedicated to a specific screen of an app. Think of it as something that handles and displays all the associated work that drives the functionality for that screen.

Since your app will have at least have one or two functions, it would make sense to spread them across a few screens so your interface isn’t cluttery. To create a screen, you create a new Java class and have it extend Activity like so:

public class MainMenuActivity extends Activity {

}

Just like that, you stub out an area of your app for a specific purpose. Your Activity doesn’t yet know its purpose because you haven’t told it what to do or how to appear.

You can create your activity’s appearance, aka Layout, one of two ways:

  • Declare it in an XML file
  • Programatically create it in a Java class

The more common approach is creating the layout in an XML file. You’d take the programmatic approach if you need to tailor some aspect of your layout.

This article won’t take you take through either process for creating layouts, but understanding how to do it is helpful if you intend to write apps for Android, because it’s a regular task. Learn more about layouts from Android’s documentation.

The following code snippet demonstrates how you would specify that an activity should determine its appearance using the XML layout in res/layout/activity_main_menu.xml.

public class MainMenuActivity extends Activity {
  // 1
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // 2

    setContentView(R.layout.activity_main_menu); // 3
  }
}

Take a look at it bit-by-bit:

  1. First, you override onCreate(), one of the methods available to you in an Activity. It runs when your Activity is created, giving you ample time to set up anything you need. This is often the first method you create for an Activity.
  2. You then call the superclass implementation of onCreate() to ensure any set up required for the Activity is performed. This is a required step. If you don’t do it, your app will crash with an exception warning.
  3. Finally, you tell your Activity to show a screen by using setContentView(), passing in a layout that’s referenced from R.

Note: R is a special class generated by Android for your app’s various assets. These could be a screen layout like you see above, or it could be something like a localized string, image or animation. Android generates R while building, so you shouldn’t modify it at all. More information about it is available from developer.android.com.

The XML layout will most likely include elements which make up the UI. You access these elements though R in an Activity, like this:

public class MainMenuActivity extends Activity {

  TextView mTextView;
  Button mButton;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main_menu); 

    mTextView = (TextView) findViewById(R.id.textview_main_menu);
    mButton = (Button) findViewById(R.id.button_main_menu);
  }
}

The key aspect is findViewById(), which searches the XML layout for view objects specified by their ID, allowing you to manipulate them from Java. Note that you have to typecast each call into an appropriate View subclass, since findViewById() only returns a View object—the root object from which all UI components inherit.

Once you have access to the individual view elements within the Java code, you would be able to interact with them and make them perform actions as you see fit. The following code segment demonstrates adding an action for when the user clicks a button:

public class MainMenuActivity extends Activity {

  TextView mTextView;
  Button mButton;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main_menu); 

    mTextView = (TextView) findViewById(R.id.textview_main_menu);
    mButton = (Button) findViewById(R.id.button_main_menu);

    mButton.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        mTextView.setText("Hello World");
      }
    });
  }
}

The code above runs onClick() every time your button is clicked. In onClick(), you tell your TextView, initially empty, to show the text “Hello World”.

Using this simple approach to link views to your class and provide actions to perform on a certain event, you can build highly complex activities. Remember these basic steps, and you’ll be on your way to grasping how Java and Android come together.

Lets Go Modeling

Models are integral to writing an Android app. Not to be confused with the kind of model that struts down the catwalk, they allow you to create objects that consist of data structures and functionality that you can utilize to great effect.

Models exist in separate classes from your UI classes. This separation not only helps keep your app organized, but it conforms to the idea of encapsulation in Object Oriented Programming.

A typical model looks something like this:

public class ReminderList {
    
  private ArrayList mReminderArrayList;

  public ReminderList() {
    mReminderArrayList = new ArrayList<>();
  }

  public void setReminderArrayList(ArrayList reminderArrayList) {
    this.mReminderArrayList = reminderArrayList;
  }
    
  public ArrayList getReminderArrayList() {
    return mReminderArrayList;
  }
    
  public void removeLastItemFromList() {
    if (!mReminderArrayList.isEmpty()) {
        mReminderArrayList.remove(mReminderArrayList.size() - 1);
    }
  }
}

No mentions of a view or activity in sight! Just data structures, raw data types and various functions. In fact this is just a Plain Old Java Object (POJO) — no secret sauce at all. This model is perfectly encapsulated, meaning you could drop it into any Android app and start using it straight away.

When creating objects in other OOP based languages, it’s conventional to create instance variables that are defined globally within the context of the object. In Android, it’s also conventional to prefix these instance variables with an m so it’s easy to tell what is a non-public, non-static instance variable and what isn’t. It feels a bit odd at first but is a good habit to get into, especially since Android source code specifies this convention and you’d need to do it to contribute to Android source code directly.

Getters and setters for member variables are also a staple of Android development. These short methods provide the rest of your app with a way to change a member variable if needed, and they allow you to provide extra behavior when getting and setting member variables.

Access Modifiers

One final piece of the puzzle that helps setters and getters work is access modifiers. Take a look at the following snippet from the model above:

private ArrayList mReminderArrayList;

public void setReminderArrayList(ArrayList reminderArrayList) {
  this.mReminderArrayList = reminderArrayList;
}

Notice the private and public keywords? These are access modifiers and they’re responsible for specifying which elements of your model class are accessible to other classes, helping to encapsulate your objects.

  • Public — accessible by all other objects. The public methods and variables form the API of the class.
  • Private — only accessible to this object. Not even available to subclasses.
  • Protected — accessible to this object and its subclasses. Not available to any other objects.

Member variables should always be set to private or protected. Access to them from outside the class should be via public getters and setters, as demonstrated in the above code snippet. This avoids hard-to-trace side-effects and tightly-coupled code.

If you made a subclass of the model above and wanted your subclass to have access to mReminderArrayList, you would change its access modifier to protected. This grants access to that variable in your subclass, while allowing you to further customize or work with that variable.

Contributors

Over 300 content creators. Join our team.