2.1: Activities and intents
Contents:
- Introduction
- About Activity
- Creating an Activity
- About Intent
- Starting an Activity with an explicit Intent
- Passing data from one Activity to another
- Getting data back from an Activity
- Activity navigation
- Related practical
- Learn more
Introduction
In this chapter you learn about the Activity
class, the major building block of your app's user interface (UI). You also learn about using an Intent
to communicate from one activity to another.
About activities
An activity represents a single screen in your app with an interface the user can interact with. For example, an email app might have one activity that shows a list of new emails, another activity to compose an email, and another activity for reading individual messages. Your app is probably a collection of activities that you create yourself, or that you reuse from other apps.
Although the activities in your app work with each other to form a cohesive user experience, each activity is independent of the others. This enables your app to start an activity in another app, and it enables other apps to start activities in your app (if your app allows this). For example, a messaging app could start an activity in a camera app to take a picture, then start an activity in an email app to let the user share the picture in email.
Typically, one Activity
in an app is specified as the "main" activity, for example MainActivity
. The user sees the main activity when they launch the app for the first time. Each activity can start other activities to perform different actions.
Each time a new activity starts, the previous activity is stopped, but the system preserves the activity in a stack (the "back stack"). When the user is done with the current activity and presses the Back button, the activity is popped from the stack and destroyed, and the previous activity resumes.
When an activity is stopped because a new activity starts, the first activity is notified by way of the activity lifecycle callback methods. The activity lifecycle is the set of states an Activity
can be in: when the activity is first created, when it's stopped or resumed, and when the system destroys it. You learn more about the activity lifecycle in a later chapter.
Creating an Activity
To implement an Activity
in your app, do the following:
- Create an
Activity
Java class. - Implement a basic UI for the
Activity
in an XML layout file. - Declare the new
Activity
in theAndroidManifest.xml
file.
When you create a new project for your app, or add a new Activity
to your app by choosing File > New > Activity, the template automatically performs the steps listed above.
Create the Activity
When you create a new project in Android Studio and choose the Backwards Compatibility (AppCompat) option, the MainActivity
is, by default, a subclass of the AppCompatActivity
class. The AppCompatActivity
class lets you use up-to-date Android app features such as the app bar and Material Design, while still enabling your app to be compatible with devices running older versions of Android.
Here is a skeleton subclass of AppCompatActivity
:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
The first task for you in your Activity
subclass is to implement the standard Activity
lifecycle callback methods (such as onCreate()
) to handle the state changes for your Activity
. These state changes include things such as when the Activity
is created, stopped, resumed, or destroyed. You learn more about the Activity
lifecycle and lifecycle callbacks in a different chapter.
The one required callback your app must implement is the onCreate()
method. The system calls this method when it creates your Activity
, and all the essential components of your Activity
should be initialized here. Most importantly, the onCreate()
method calls setContentView()
to create the primary layout for the Activity
.
You typically define the UI for your Activity
in one or more XML layout files. When the setContentView()
method is called with the path to a layout file, the system creates all the initial views from the specified layout and adds them to your Activity
. This is often referred to as inflating the layout.
You may often also want to implement the onPause()
method in your Activity
. The system calls this method as the first indication that the user is leaving your Activity
(though it does not always mean that the Activity
is being destroyed). This is usually where you should commit any changes that should be persisted beyond the current user session (because the user might not come back). You learn more about onPause()
and all the other lifecycle callbacks in a later chapter.
In addition to lifecycle callbacks, you may also implement methods in your Activity
to handle other behavior such as user input or button clicks.
Implement the activity's UI
The UI for an activity is provided by a hierarchy of View
elements, which controls a particular space within the activity window and can respond to user interaction.
The most common way to define a UI using View
elements is with an XML layout file stored as part of your app's resources. Defining your layout in XML enables you to maintain the design of your UI separately from the source code that defines the activity behavior.
You can also create new View
elements directly in your activity code by inserting new View
objects into a ViewGroup
, and then passing the root ViewGroup
to setContentView()
. After your layout has been inflated—regardless of its source—you can add more View
elements anywhere in the View
hierarchy.
Declare the Activity in AndroidManifest.xml
Each Activity
in your app must be declared in the AndroidManifest.xml
file with the <activity>
element, inside the <application>
section. When you create a new project or add a new Activity
to your project in Android Studio, the AndroidManifest.xml
file is created or updated to include skeleton declarations for each Activity
. Here's the declaration for MainActivity
:
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
The <activity>
element includes a number of attributes to define properties of the Activity
such as its label, icon, or theme. The only required attribute is android:name
, which specifies the class name for the Activity
(such as MainActivity
). See the <activity>
element reference for more information on Activity
declarations.
The <activity>
element can also include declarations for Intent
filters. The Intent
filters specify the kind of Intent
your Activity
will accept.
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
Intent
filters must include at least one <action>
element, and can also include a <category>
and optional <data>
. The MainActivity
for your app needs an Intent
filter that defines the "main" action and the "launcher" category so that the system can launch your app. Android Studio creates this Intent
filter for the MainActivity
in your project.
The <action>
element specifies that this is the "main" entry point to the app. The <category>
element specifies that this Activity
should be listed in the system's app launcher (to allow users to launch this Activity
).
Each Activity
in your app can also declare Intent
filters, but only your MainActivity
should include the "main" action. You learn more about how to use an implicit Intent
and Intent
filters in a later section.
Add another Activity to your project
The MainActivity
for your app and its associated layout file is supplied by an Activity
template in Android Studio such as Empty Activity or Basic Activity. You can add a new Activity
to your project by choosing File > New > Activity. Choose the Activity
template you want to use, or open the Gallery to see all the available templates.
When you choose an Activity
template, you see the same set of screens for creating the new activity that you did when you created the project. Android Studio provides three things for each new activity in your app:
- A Java file for the new
Activity
with a skeleton class definition andonCreate()
method. The newActivity
, likeMainActivity
, is a subclass ofAppCompatActivity
. - An XML file containing the layout for the new activity. Note that the
setContentView()
method in theActivity
class inflates this new layout. - An additional
<activity>
element in theAndroidManifest.xml
file that specifies the new activity. The secondActivity
definition does not include anyIntent
filters. If you plan to use this activity only within your app (and not enable that activity to be started by any other app), you do not need to add filters.
About intents
Each activity is started or activated with an Intent
, which is a message object that makes a request to the Android runtime to start an activity or other app component in your app or in some other app.
When your app is first started from the device home screen, the Android runtime sends an Intent
to your app to start your app's main activity (the one defined with the MAIN action and the LAUNCHER category in the AndroidManifest.xml
file). To start another activity in your app, or to request that some other activity available on the device perform an action, you build your own intent and call the startActivity()
method to send the intent.
In addition to starting an activity, an intent can also be used to pass data between one activity and another. When you create an intent to start a new activity, you can include information about the data you want that new activity to operate on. So, for example, an email Activity
that displays a list of messages can send an Intent
to the Activity
that displays that message. The display activity needs data about the message to display, and you can include that data in the intent.
In this chapter you learn about using intents with activities, but intents can also be used to start services or broadcast receivers. You learn how to use those app components in another practical.
Intent types
Intents can be explicit or implicit:
- Explicit intent: You specify the receiving activity (or other component) using the activity's fully qualified class name. You use explicit intents to start components in your own app (for example, to move between screens in the UI), because you already know the package and class name of that component.
- Implicit intent: You do not specify a specific activity or other component to receive the intent. Instead, you declare a general action to perform, and the Android system matches your request to an activity or other component that can handle the requested action. You learn more about using implicit intents in another practical.
Intent objects and fields
For an explicit Intent
, the key fields include the following:
- The
Activity
class (for an explicitIntent
). This is the class name of theActivity
or other component that should receive theIntent
; for example,com.example.SampleActivity.class
. Use theIntent
constructor or thesetComponent()
,setComponentName()
, orsetClassName()
methods to specify the class. - The
Intent
data. TheIntent
data field contains a reference to the data you want the receivingActivity
to operate on as a Uri object. Intent
extras. These are key-value pairs that carry information the receivingActivity
requires to accomplish the requested action.Intent
flags. These are additional bits of metadata, defined by theIntent
class. The flags may instruct the Android system how to launch anActivity
or how to treat it after it's launched.
For an implicit Intent
, you may need to also define the Intent
action and category. You learn more about Intent
actions and categories in another chapter.
Starting an Activity with an explicit Intent
To start a specific Activity
from another Activity
, use an explicit Intent
and the startActivity()
method. An explicit Intent
includes the fully qualified class name for the Activity
or other component in the Intent
object. All the other Intent
fields are optional, and null
by default.
For example, if you want to start the ShowMessageActivity
to show a specific message in an email app, use code like this:
Intent messageIntent = new Intent(this, ShowMessageActivity.class);
startActivity(messageIntent);
The intent constructor takes two arguments for an explicit Intent
:
- An application context. In this example, the
Activity
class provides the context (this
). - The specific component to start (
ShowMessageActivity.class
).
Use the startActivity()
method with the new Intent
object as the only argument. The startActivity()
method sends the Intent
to the Android system, which launches the ShowMessageActivity
class on behalf of your app. The new Activity
appears on the screen, and the originating Activity
is paused.
The started Activity
remains on the screen until the user taps the Back button on the device, at which time that Activity
closes and is reclaimed by the system, and the originating Activity
is resumed. You can also manually close the started Activity
in response to a user action (such as a Button
click) with the finish()
method:
public void closeActivity (View view) {
finish();
}
Passing data from one Activity to another
In addition to simply starting one Activity
from another Activity
, you also use an Intent
to pass information from one Activity
to another. The Intent
object you use to start an Activity
can include Intent
data (the URI of an object to act on), or Intent
extras, which are bits of additional data the Activity
might need.
In the first (sending) Activity
, you:
- Create the
Intent
object. - Put data or extras into that
Intent
. - Start the new
Activity
withstartActivity()
.
In the second (receiving) Activity
, you:
- Get the
Intent
object theActivity
was started with. - Retrieve the data or extras from the
Intent
object.
When to use Intent data or Intent extras
You can use either Intent
data or Intent
extras to pass data from one Activity
to another. There are several key differences between data and extras that determine which you should use.
The Intent
data can hold only one piece of information: a URI representing the location of the data you want to operate on. That URI could be a web page URL (http://
), a telephone number (tel://
), a geographic location (geo://
) or any other custom URI you define.
Use the Intent
data field:
- When you only have one piece of information you need to send to the started
Activity
. - When that information is a data location that can be represented by a URI.
Intent extras are for any other arbitrary data you want to pass to the started Activity
. Intent
extras are stored in a Bundle
object as key and value pairs. A Bundle
is a map, optimized for Android, in which a key is a string, and a value can be any primitive or object type (objects must implement the Parcelable
interface). To put data into the Intent
extras you can use any of the Intent
class putExtra()
methods, or create your own Bundle
and put it into the Intent
with putExtras()
.
Use the Intent
extras:
- If you want to pass more than one piece of information to the started
Activity
. - If any of the information you want to pass is not expressible by a URI.
Intent
data and extras are not exclusive; you can use data for a URI and extras for any additional information the started Activity
needs to process the data in that URI.
Add data to the Intent
To add data to an explicit Intent
from the originating Activity
, create the Intent
object as you did before:
Intent messageIntent = new Intent(this, ShowMessageActivity.class);
Use the setData()
method with a Uri object to add that URI to the Intent
. Some examples of using setData()
with URIs:
// A web page URL
messageIntent.setData(Uri.parse("http://www.google.com"));
// a Sample file URI
messageIntent.setData(Uri.fromFile(new File("/sdcard/sample.jpg")));
// A sample content: URI for your app's data model
messageIntent.setData(Uri.parse("content://mysample.provider/data"));
// Custom URI
messageIntent.setData(Uri.parse("custom:" + dataID + buttonId));
Keep in mind that the data field can only contain a single URI; if you call setData()
multiple times only the last value is used. Use Intent
extras to include additional information (including URIs.)
After you've added the data, you can start the Activity
with the Intent
as usual:
startActivity(messageIntent);
Add extras to the Intent
To add Intent
extras to an explicit Intent
from the originating Activity
:
- Determine the keys to use for the information you want to put into the extras, or define your own. Each piece of information needs its own unique key.
- Use the
putExtra()
methods to add your key/value pairs to theIntent
extras. Optionally you can create aBundle
object, add your data to theBundle
, and then add theBundle
to theIntent
.
The Intent
class includes extra keys you can use, defined as constants that begin with the word EXTRA_
. For example, you could use Intent.EXTRA_EMAIL
to indicate an array of email addresses (as strings), or Intent.EXTRA_REFERRER
to specify information about the originating Activity
that sent the Intent
.
You can also define your own Intent
extra keys. Conventionally you define Intent
extra keys as static variables with names that begin with EXTRA_
. To guarantee that the key is unique, the string value for the key itself should be prefixed with your app's fully qualified class name. For example:
public final static String EXTRA_MESSAGE =
"com.example.mysampleapp.MESSAGE";
public final static String EXTRA_POSITION_X = "com.example.mysampleapp.X";
public final static String EXTRA_POSITION_Y = "com.example.mysampleapp.Y";
Create an Intent
object (if one does not already exist):
Intent messageIntent = new Intent(this, ShowMessageActivity.class);
Use a putExtra()
method with a key to put data into the Intent
extras. The Intent
class defines many putExtra()
methods for different kinds of data:
messageIntent.putExtra(EXTRA_MESSAGE, "this is my message");
messageIntent.putExtra(EXTRA_POSITION_X, 100);
messageIntent.putExtra(EXTRA_POSITION_Y, 500);
Alternately, you can create a new Bundle
and populate that Bundle
with your Intent
extras. Bundle
defines many "put" methods for different kinds of primitive data as well as objects that implement Android's Parcelable
interface or Java's Serializable
.
Bundle extras = new Bundle();
extras.putString(EXTRA_MESSAGE, "this is my message");
extras.putInt(EXTRA_POSITION_X, 100);
extras.putInt(EXTRA_POSITION_Y, 500);
After you've populated the Bundle
, add it to the Intent
with the putExtras()
method (note the "s" in Extras
):
messageIntent.putExtras(extras);
Start the Activity
with the Intent
as usual:
startActivity(messageIntent);
Retrieve the data from the Intent in the started Activity
When you start an Activity
with an Intent
, the started Activity
has access to the Intent
and the data it contains.
To retrieve the Intent
the Activity
(or other component) was started with, use the getIntent()
method:
Intent intent = getIntent();
Use getData()
to get the URI from that Intent
:
Uri locationUri = intent.getData();
To get the extras out of the Intent
, you need to know the keys for the key/value pairs. You can use the standard Intent
extras if you used those, or you can use the keys you defined in the originating Activity
(if they were defined as public.)
Use one of the getExtra()
methods to extract extra data out of the Intent
object:
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
int positionX = intent.getIntExtra(MainActivity.EXTRA_POSITION_X);
int positionY = intent.getIntExtra(MainActivity.EXTRA_POSITION_Y);
Or you can get the entire extras Bundle
from the Intent
and extract the values with the various Bundle
methods:
Bundle extras = intent.getExtras();
String message = extras.getString(MainActivity.EXTRA_MESSAGE);
Getting data back from an Activity
When you start an Activity
with an Intent
, the originating Activity
is paused, and the new Activity
remains on the screen until the user clicks the Back button, or you call the finish()
method in a click handler or other function that ends the user's involvement with this Activity
.
Sometimes when you send data to an Activity
with an Intent
, you would like to also get data back from that Intent
. For example, you might start a photo gallery Activity
that lets the user pick a photo. In this case your original Activity
needs to receive information about the photo the user chose back from the launched Activity
.
To launch a new Activity
and get a result back, do the following steps in your originating Activity
:
- Instead of launching the
Activity
withstartActivity()
, callstartActivityForResult()
with theIntent
and a request code. - Create a new
Intent
in the launchedActivity
and add the return data to thatIntent
. - Implement
onActivityResult()
in the originatingActivity
to process the returned data.
You learn about each of these steps in the following sections.
Use startActivityForResult() to launch the Activity
To get data back from a launched Activity
, start that Activity
with the startActivityForResult()
method instead of startActivity()
.
startActivityForResult(messageIntent, TEXT_REQUEST);
The startActivityForResult()
method, like startActivity()
, takes an Intent
argument that contains information about the Activity
to be launched and any data to send to that Activity
. The startActivityForResult()
method, however, also needs a request code.
The request code is an integer that identifies the request and can be used to differentiate between results when you process the return data. For example, if you launch one Activity
to take a photo and another to pick a photo from a gallery, you need different request codes to identify which request the returned data belongs to.
Conventionally you define request codes as static integer variables with names that include REQUEST
. Use a different integer for each code. For example:
public static final int PHOTO_REQUEST = 1;
public static final int PHOTO_PICK_REQUEST = 2;
public static final int TEXT_REQUEST = 3;
Return a response from the launched Activity
The response data from the launched Activity
back to the originating Activity
is sent in an Intent
, either in the data or the extras. You construct this return Intent
and put the data into it in much the same way you do for the sending Intent
. Typically your launched Activity
will have an onClick()
or other user input callback method in which you process the user's action and close the Activity
. This is also where you construct the response.
To return data from the launched Activity
, create a new empty Intent
object.
Intent returnIntent = new Intent();
Intent
object rather than reusing the original sending Intent
object.
A return result Intent
does not need a class or component name to end up in the right place. The Android system directs the response back to the originating Activity
for you.
Add data or extras to the Intent
the same way you did with the original Intent
. You may need to define keys for the return Intent
extras at the start of your class.
public final static String EXTRA_RETURN_MESSAGE =
"com.example.mysampleapp.RETURN_MESSAGE";
Then put your return data into the Intent
as usual. In the following, the return message is an Intent
extra with the key EXTRA_RETURN_MESSAGE
.
messageIntent.putExtra(EXTRA_RETURN_MESSAGE, mMessage);
Use the setResult()
method with a response code and the Intent
with the response data:
setResult(RESULT_OK,replyIntent);
The response codes are defined by the Activity
class, and can be
RESULT_OK
: The request was successful.RESULT_CANCELED
: The user canceled the operation.RESULT_FIRST_USER
: For defining your own result codes.
You use the result code in the originating Activity
.
Finally, call finish()
to close the Activity
and resume the originating Activity
:
finish();
Read response data in onActivityResult()
Now that the launched Activity
has sent data back to the originating Activity
with an Intent
, that first Activity
must handle that data. To handle returned data in the originating Activity
, implement the onActivityResult()
callback method. Here is a simple example.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TEXT_REQUEST) {
if (resultCode == RESULT_OK) {
String reply =
data.getStringExtra(SecondActivity.EXTRA_RETURN_MESSAGE);
// process data
}
}
}
The three arguments to onActivityResult()
contain all the information you need to handle the return data.
- Request code: The request code you set when you launched the
Activity
withstartActivityForResult()
. If you launch a differentActivity
to accomplish different operations, use this code to identify the specific data you're getting back. - Result code: the result code set in the launched
Activity
, usually one ofRESULT_OK
orRESULT_CANCELED
. - Intent data: the
Intent
that contains the data returned from the launchActivity
.
The example method shown above shows the typical logic for handling the request and response codes. The first test is for the TEXT_REQUEST
request, and that the result was successful. Inside the body of those tests you extract the return information out of the Intent
. Use getData()
to get the Intent
data, or getExtra()
to retrieve values out of the Intent
extras with a specific key.
Activity navigation
Any app of any complexity that you build will include more than one Activity
. As your users move around your app and from one Activity
to another, consistent navigation becomes more important to the app's user experience. Few things frustrate users more than basic navigation that behaves in inconsistent and unexpected ways. Thoughtfully designing your app's navigation will make using your app predictable and reliable for your users.
Android system supports two different forms of navigation strategies for your app.
- Back (temporal) navigation, provided by the device Back button, and the back stack.
- Up (ancestral) navigation, provided by you as an option in the app bar.
Back navigation, tasks, and the back stack
Back navigation allows your users to return to the previous Activity
by tapping the device back button
. Back navigation is also called temporal navigation because the back button navigates the history of recently viewed screens, in reverse chronological order.
The back stack is the set of each Activity
that the user has visited and that can be returned to by the user with the back button. Each time a new Activity
starts, it is pushed onto the back stack and takes user focus. The previous Activity
is stopped but is still available in the back stack. The back stack operates on a "last in, first out" mechanism, so when the user is done with the current Activity
and presses the Back button, that Activity
is popped from the stack (and destroyed) and the previous Activity
resumes.
Because an app can start an Activity
both inside and outside a single app, the back stack contains each Activity
that has been launched by the user in reverse order. Each time the user presses the Back button, each Activity
in the stack is popped off to reveal the previous one, until the user returns to the Home screen.
Android provides a back stack for each task. A task is an organizing concept for each Activity
the user interacts with when performing an operation, whether they are inside your app or across multiple apps. Most tasks start from the Android home screen, and tapping an app icon starts a task (and a new back stack) for that app. If the user uses an app for a while, taps home, and starts a new app, that new app launches in its own task and has its own back stack. If the user returns to the first app, that first task's back stack returns. Navigating with the Back button returns only to the Activity
in the current task, not for all tasks running on the device. Android enables the user to navigate between tasks with the overview or recent tasks screen, accessible with the square button on lower right corner of the device
.
In most cases you don't have to worry about managing either tasks or the back stack for your app—the system keeps track of these things for you, and the back button is always available on the device.
There may, however, be times where you may want to override the default behavior for tasks or for the back stack. For example, if your screen contains an embedded web browser where users can navigate between web pages, you may wish to use the browser's default back behavior when users press the device's Back button, rather than returning to the previous Activity
. You may also need to change the default behavior for your app in other special cases such as with notifications or widgets, where an Activity
deep within your app may be launched as its own task, with no back stack at all. You learn more about managing tasks and the back stack in a later section.
Up navigation
Up navigation, sometimes referred to as ancestral or logical navigation, is used to navigate within an app based on the explicit hierarchical relationships between screens. With Up navigation, each Activity
is arranged in a hierarchy, and each "child" Activity
shows a left-facing arrow in the app bar
that returns the user to the "parent" Activity
. The topmost Activity
in the hierarchy is usually MainActivity
, and the user cannot go up from there.
For instance, if the main Activity
in an email app is a list of all messages, selecting a message launches a second Activity
to display that single email. In this case the message Activity
would provide an Up button that returns to the list of messages.
The behavior of the Up button is defined by you in each Activity
based on how you design your app's navigation. In many cases, Up and Back navigation may provide the same behavior: to just return to the previous Activity
. For example, a Settings Activity
may be available from any Activity
in your app, so "up" is the same as back—just return the user to their previous place in the hierarchy.
Providing Up behavior for your app is optional, but a good design practice, to provide consistent navigation for your app.
Implement Up navigation with a parent Activity
With the standard template projects in Android Studio, it's straightforward to implement Up navigation. If one Activity
is a child of another Activity
in your app's Activity
hierarchy, specify the parent of that other Activity
in the AndroidManifest.xml
file.
Beginning in Android 4.1 (API level 16), declare the logical parent of each Activity
by specifying the android:parentActivityName
attribute in the <activity>
element. To support older versions of Android, include <meta-data>
information to define the parent Activity
explicitly. Use both methods to be backwards-compatible with all versions of Android.
The following are the skeleton definitions in AndroidManifest.xml
for both a main (parent) Activity
(MainActivity
) and a second (child) Activity
(SecondActivity
):
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- The main activity (it has no parent activity) -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- The child activity) -->
<activity android:name=".SecondActivity"
android:label = "Second Activity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.android.twoactivities.MainActivity" />
</activity>
</application>
You learn more about Up navigation and other user navigation features in another practical.
Related practical
The related practical is 2.1: Activities and intents.
Learn more
Android Studio documentation:
Android developer documentation: