Skip to content

Latest commit

 

History

History
 
 

lesson2

Lesson #2
Activities and Views

Learning goals

  • Working with Activities, and get basic understanding of the Activity Life Cycle,
  • Debugging basics,
  • Becoming familiar with common Views or widgets and how to add them to an Activity,
  • Interacting with these views in your code, such as listen to events.

If you know all about the learning goals for this lesson move on to lesson 3.

Activities

An activity usually is a full Android screen that a user sees or interacts with. The onCreate() method you saw in the MainActivity in lesson 1 is what we call a life cycle callback method and this gives you a hook where you can initialize your activity when the Android system decides it is time to show your activity to the user. The Activity life cycle is very important and deserves good understanding when you are planning to do more Android development after this workshop.

The MainActivity launch intent filter

When the user selects your app icon from the Home screen, the system calls the onCreate() method for the Activity in your app that you've declared to be the "launcher" (or "main") activity. This is the activity that serves as the main entry point to your app's user interface.

You can define which activity to use as the main activity in the Android manifest file, AndroidManifest.xml, which is at the root of your project directory.

The main activity for your app must be declared in the AndroidManifest.xml file with an <intent-filter> that includes the MAIN action and LAUNCHER category. For example:

<activity
        android:label="@string/app_name"
        android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>

If either the MAIN action or LAUNCHER category are not declared for one of your activities, then your app icon will not appear in the Home screen's list of apps.

The Activity Life Cycle

During the life of an activity, the system calls a core set of lifecycle methods in a sequence similar to a step pyramid. That is, each stage of the activity lifecycle is a separate step on the pyramid. As the system creates a new activity instance, each callback method moves the activity state one step toward the top. The top of the pyramid is the point at which the activity is running in the foreground and the user can interact with it.

As the user begins to leave the activity, the system calls other methods that move the activity state back down the pyramid in order to dismantle the activity. In some cases, the activity will move only part way down the pyramid and wait (such as when the user switches to another app), from which point the activity can move back to the top (if the user returns to the activity) and resume where the user left off.

The Activity Life Cycle

Figure 1. A simplified illustration of the Activity lifecycle, expressed as a step pyramid. This shows how, for every callback used to take the activity a step toward the Resumed state at the top, there's a callback method that takes the activity a step down. The activity can also return to the resumed state from the Paused and Stopped state.

Using logcat

The Android logging system provides a mechanism for collecting and viewing system debug output. Logs from various applications and portions of the system are collected in a series of circular buffers, which then can be viewed and filtered by the adb logcat command, or directly from Android Studio by pressing the Android Toolbar quick pick button on the control bar at the bottom or selecting “View” → “Tool Windows” → “Android” from the menu.

More info

Selecting the Android tool window from the menu

A good way to keep an eye on which life cycle method is called when is to simple create a log statement in the life cycle method overrides. For example in the onCreate method.

public void onCreate(Bundle savedInstanceState) {
	Log.d(TAG, "onCreate");
	super.onCreate(savedInstanceState);
}

You simply call a log-level static method (d, which stands for debug) where TAG is a (class) constant with a String you can filter on in your logcat session and the "onCreate" string represents the log message in this example. Some people use a single TAG for the whole application, but most use the following construct to create a unique tag for every class.

private static final String TAG = MainActivity.class.getSimpleName();

You can add your TAG in the filter box in the Android tool window, or view the logcat output with the following adb command in a terminal

> adb logcat MainActivity:* *:S

The parameters after the logcat statement are filters in the form [TAG]:[log-level]. I.e. MainActivity:I will only show information messages and higher and MainActivity:* will show all log-level outputs for the MainActivity tag. The *:S filter says to silence all the other output. It is advisable to also add a AndroidRuntime:* filter as this will show you relevant information from the Android system as well as exceptions that are generated by your application but caught by the platform.

If you are just interested in which methods are called when, you can just use Jake Wharton's Hugo library.

Add this to your build.gradle file

buildscript {
  dependencies {
    classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
  }
}

apply plugin: 'android'
apply plugin: 'hugo'

And than add the @DebugLog annotation to any method you want to debug log.

A couple of the Activity life cycle methods in the MainActivity in this lesson are annotated with the @DebugLog annotation. Take that project for a spin to get a grasp of how your activity is managed by the system. Tip, rotate your device and see what happens. Can you explain why this happens?

Exercises

Exercise 2.1: Adding new views to the layout

Open the activity_main.xml file in the lesson2 project in Android Studio and click on the Design tab next to the Text tab below. You should see something like this.

Android Design Tool View

Android Design Tool View

On the left you see a long list of Views or widgets. Grab a Person Name from the Text Fields section and place it under the TextView view. Grab a Button from the Widgets section and place it under the EditText view.

Exercise 2.2: Referencing views in the layout in your code

To get a reference to the views in the layout in your code you can create a resource-id for every view you want to interact with. Creating an id is done by adding an android:id attribute to the views and giving them an (e.g.) @+id/uniquenameforyourview value. The "@"-sign identifies a resource (we already saw references to string resources via @string/app_name for instance). The "+"-sign just before the id indicates we want to create and id. If we forget the "+"-sign the @id/uniquenameforyourview becomes a reference.

Go ahead and add android:id attributes to the TextView, EditText and Button views in the activity_main.xml file.

Now open the MainActivity file in Android Studio. When our acitivity is created (in onCreate()) and our contentView is set the layout in the XML file gets inflated by the Android System. This basically means whatever is in the XML file will be used to create a View hierarchy of plain Java objects we can interact with in our code. We can only create references to our views in the layout, if they have a proper id. We can reference them by calling the findViewById(int id) method like this.

TextView textView = (TextView) findViewById(R.id.uniquenameforyourview);

Go ahead and hook-up all the views in the onCreate() method in MainActivity. Make fields out of the view references while you are at it, so you can reference them from other methods in your class (not just the onCreate method).

Exercise 2.3: Interacting with the views

You can [click on any view](http://developer.android.com/reference/android/view/View.html#setOnClickListener(android.view.View.OnClickListener) in Android, but Buttons are, of course, the ideal things to click on. You can listen to a button click by implementing- and adding a View.OnClickListener to your button.

button.setOnClickListener(this);

What we are saying here is that our MainActivity should implement the View.OnClickListener interface. If you have added the above line in your onCreate() method you'll see a red curly line under the this reference. Move your cursor on the this keyword and press Alt+Enter. Select the second option. You are then prompted to implement the onClick() method, which is just what we need

Android Studio quick-fix

Now in the onClick(View v) method try to read the value from the EditText reference and use that value to update the TextView reference.

Exercise 2.4: Change the app icon

By default you get this standard app launch icon for new Android projects:

Default launch icon

Default launch icon

Use Android Studio's built-in image resource generator to create a new launch icon.

Default launch icon

Android Studio's image asset generator

You can also use the online Android Asset Studio.

Exercise 2.5: Change the Activity title

The title of the MainActivity is set via the android:label="@string/app_name" attribute in the AndroidManifest.xml file. Use another string and try to change the title of the MainActivity class in the onCreate() method.

Exercise 2.6: Change the background color

Try to change the background color of the MainActivity in the activity_main.xml file.

Conclusion

You've learned how to add more Views to your layout and how to reference and interact with them in your code. You have seen methods to log (debug) statements to Android's logcat.

On to lesson 3, where you will learn more about the activity back stack and how to move from one Activity to another with explicit and implicit Intents.