Chapter 2

Activities

In Chapter 1, “Your First Application” you learned to write a simple Android application. It is now time to delve deeper into the art and science of Android development. This chapter discusses one of the most important component types in Android programming, the activity.

The Activity Lifecycle

The first application component that you need to get familiar with is the activity. An activity is a thing that the user can do. This definition sounds vague, especially for beginners. However, considering that  most activities involve displaying a window containing user interface (UI) components that the user can interact with, you can liken an activity to a window. Therefore, starting an activity often means displaying a window.

All activities are represented by the android.app.Activity class. You create an activity by subclassing this class.

An typical Android application starts by starting an activity, which, as I said, loosely means showing a window. The first window that the application creates is called the main activity and serves as the entry point to the application. Needless to say, an Android application may contain multiple activities and you specify the main activity by declaring it in the application manifest file.

For example, the following application element in an Android manifest defines two activities, one of which is declared as the main activity using the intent-filter element. To make an activity the main activity of an application, its intent-filter element must contain the MAIN action and LAUNCHER category like so.

 

<application ... >

    <activity

            android:name="com.example.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>

    <activity

            android:name="com.example.SecondActivity"

            android:label="@string/title_activity_second" >

    </activity>

</application>

In the snippet above, it is not hard to see that the first activity is the main activity.

When the user selects your application icon from the Home screen, the system will look for the main activity of the application and start it. Starting an activity entails instantiating the activity class (which is specified by the android:name attribute of the activity element in the manifest) and calling its lifecycle methods. It is important that you understand these methods so you can write code correctly.

The following are the lifecycle methods of Activity. Some are called once during the application lifetime, some can be called more than once.

 

▪  onCreate

▪  onStart

▪  onResume

▪  onPause

▪  onStop

▪  onRestart

▪  onDestroy

To truly understand how these lifecycle methods come into play, consider the diagram in Figure 2.1.

 2_1

Figure 2.1: The activity lifecycle

The system begins by calling the onCreate method to create the activity. You should place the code that constructs the UI here. Once onCreate is completed, your application is said to be in the Created state. This method will only be called once during the application life time.

Next, the system calls the activity’s onStart method. When this method is called, the application becomes visible. Once this method is completed, the application is in the Started state. This method may be called more than once during the application life time.

onStart is followed by onResume and once onResume is completed, the application is in the Resumed state. How I wish they had called it Running instead of Resumed, because the fact is this is the state where your application is fully running. onResume may be called multiple times during the application life time.

Therefore, onCreated, onStart, and onResume will be called successively unless something goes awry during the process. Once in the Resumed state, the application is basically running and will stay in this state until something occurs to change that, such as if the alarm clock sets off or the screen turns off because the device is going to sleep, or perhaps because another application is started.

The application that is leaving the Resumed state will have its running activity’s onPause method called. Once onPause is completed, the application enters the Paused state. onPause can be called multiple times during the application life time.

What happens after onPause depends on whether or not your application becomes completely invisible. If it does, the onStop method is called and the application enters the Stopped state. On the other hand, if the application becomes active again after onPause, the system calls the onResume method and the application re-enters the Resumed state.

An application in the Stopped state may be re-activated if the user chooses to go back to the application or for some other reason it goes back to the foreground. In this case, the onRestart method will be called, followed by onStart.

Finally, when the application is decommissioned, its onDestroy method is called. This method, like onCreate, can only be called once during the application life time.

ActivityDemo Example

The ActivityDemo application accompanying this book demonstrates when the activity lifecycle methods are called. Listing 2.1 shows the manifest for this application.

Listing 2.1: The manifest for ActivityDemo

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.activitydemo"

    android:versionCode="1"

    android:versionName="1.0" >

 

    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="18" />

 

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name="com.example.activitydemo.MainActivity"

            android:screenOrientation="landscape"

            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>

This manifest is like the one in Chapter 1, “Your First Application.” It has one activity, the main activity. However, notice that we specify the orientation of the activity using the android:screenOrientation attribute of the activity element.

The main class for this application is printed in Listing 2.2. The class overrides all the lifecycle methods of Activity and prints a debug message in each lifecycle method.

Listing 2.2: The MainActivity class for ActivityDemo

package com.example.activitydemo;

 

import android.os.Bundle;

import android.app.Activity;

import android.util.Log;

import android.view.Menu;

 

public class MainActivity extends Activity {

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        Log.d("lifecycle", "onCreate");

        setContentView(R.layout.activity_main);

    }

 

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.

        getMenuInflater().inflate(R.menu.main, menu);

        return true;

    }

   

    @Override

    public void onStart() {

        super.onStart();

        Log.d("lifecycle", "onStart");

    }

   

    @Override

    public void onRestart() {

        super.onRestart();

        Log.d("lifecycle", "onRestart");       

    }

 

    @Override

    public void onResume() {

        super.onResume();

        Log.d("lifecycle", "onResume");       

    }

 

    @Override

    public void onPause() {

        super.onPause();

        Log.d("lifecycle", "onPause");       

    }

 

    @Override

    public void onStop() {

        super.onStop();

        Log.d("lifecycle", "onStop");       

    }

 

    @Override

    public void onDestroy() {

        super.onDestroy();

        Log.d("lifecycle", "onDestroy");

    }

}

Before you run this application, create a Logcat message filter to show only messages from the application, filtering out system messages, by following these steps.

 

1.     Click the green Plus sign on the Saved Filter pane in LogCat.

2.     Type in a name in the Filter Name field and lifecycle in the by Log Message field. Next, select debug from the by Log Level dropdown. Figure 2.2 shows the Logcat Message Filter Settings window.

2_2 

Figure 2.2: Creating a Logcat message filter

3. Click OK to create the filter.

Run the application and notice the orientation of the application. It should be landscape. Now, try running another application and then switch back to the ActivityDemo application. Check the messages printed in Logcat.

Starting Another Activity

The main activity of an Android application is started by the system itself, when the user selects the app icon from the Home screen. In an application with multiple activities, it is possible (and easy) to start another activity. In fact, starting an activity from another activity can be done simply by calling the startActivity method like this.

startActivity(intent);

where intent is an instance of Intent.

As an example, consider the SecondActivityTest project that accompanies this book. It has two activities, MainActivity and SecondActivity. MainActivity contains a button that when clicked starts SecondActivity. This project also shows how you can write an event listener programmatically.

The manifest for SecondActivityTest is given in Listing 2.3.

Listing 2.3: The manifest for SecondActivityTest

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.secondactivitytest"

    android:versionCode="1"

    android:versionName="1.0" >

 

    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="19" />

 

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name="com.example.secondactivitytest.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>

        <activity

            android:name="com.example.secondactivitytest.SecondActivity"

            android:label="@string/title_activity_second" >

        </activity>

    </application>

</manifest>

Unlike other Android applications in this chapter, this project has two activities, one of which is declared as the main activity.

The layout files for the main and second activities are listed in Listings 2.4 and 2.5, respectively.

Listing 2.4: The activity_main.xml file

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".MainActivity" >

 

    <TextView

        android:id="@+id/textView1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="@string/first_screen" />

 

</RelativeLayout>

Listing 2.5: The activity_second.xml file

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".SecondActivity" >

 

    <TextView

        android:id="@+id/textView1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" />

 

</RelativeLayout>

Both activities contain a TextView. When the TextView in the main activity is touched, it will start the second activity and pass a message for the latter. The second activity will display the message in its TextView.

The activity class for the main activity is given in Listing 2.6.

Listing 2.6: The MainActivity class

package com.example.secondactivitytest;

 

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.Menu;

import android.view.MotionEvent;

import android.view.View;

import android.view.View.OnTouchListener;

import android.widget.TextView;

 

public class MainActivity extends Activity implements

        OnTouchListener {

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        TextView tv = (TextView) findViewById(R.id.textView1);

        tv.setOnTouchListener(this);

    }

 

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it

        // is present.

        getMenuInflater().inflate(R.menu.main, menu);

        return true;

    }

 

    @Override

    public boolean onTouch(View arg0, MotionEvent event) {

        Intent intent = new Intent(this, SecondActivity.class);

        intent.putExtra("message", "Message from First Screen");

        startActivity(intent);

        return true;

    }

}

To handle the touch event, the MainActivity class has implemented the OnTouchListener interface and overridden its onTouch method. In this method, you create an Intent and put a message in it. You then call the startActivity method to start the second activity.

The SecondActivity class is given in Listing 2.7.

Listing 2.7: The SecondActivity class

package com.example.secondactivitytest;

 

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.Menu;

import android.widget.TextView;

 

public class SecondActivity extends Activity {

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_second);

        Intent intent = getIntent();

        String message = intent.getStringExtra("message");

        ((TextView) findViewById(R.id.textView1)).setText(message);

    }

 

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.second, menu);

        return true;

    }

}

In the onCreate method of SecondActivity, you set the view content as usual. You then call the getIntent method and retrieve a message from its getStringExtra method, which you then pass to the setText method of the TextView. You retrieve the TextView by calling the findViewById method.

The main activity and the second activity are shown in Figures 2.3 and 2.4, respectively.

 2_3

Figure 2.3: The main activity in SecondActivityTest

 2_4

Figure 2.4: The second activity in SecondActivityTest

Summary

In this chapter you learned about the activity lifecycle and created two applications. The first application allowed you to observe when each of the lifecycle methods was called. The second application showed how to start an activity from another activity.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.136.84