Activity Navigation

Intent is an object to pass messages, which can be used to send requests to other components (activity, service, broadcast receiver, etc.) for execution. But for activities, its main usage is to start another activity.

Explicit Intent Navigation

With explicit intent, we directly tell the class name to start, which is widely adopted within applications.

Suppose we jump from MainActivity to SecondActivity

Set listener for a button
1
2
3
4
5
6
7
8
9
10
11
myButton.setOnClickListener(v -> {
// 1. create an explicit Intent object
// Arg1: context (usually this class)
// Arg2: target activity class object
Intent intent = new Intent(
MainActivity.this,
SecondActivity.class);

// 2. Start target activity
startActivity(intent);
});

Implicit Intent Navigation

Implicit is often used to interact with other apps on the phone, instead of other components within the same app. Upon calling, Android will skim through all apps and let users choose.

Implicit intent
1
2
3
4
5
6
7
8
9
// opens a website
Intent webIntent = new Intent(Intent.ACTION_VIEW);
webIntent.setData(Uri.parse("https://www.android.com"));
startActivity(webIntent);

// starts a phone call
Intent dialIntent = new Intent(Intent.ACTION_DIAL);
dialIntent.setData(Uri.parse("tel:10086"));
startActivity(dialIntent);

Data Transmission

Passing Data with Bundle

Bundle is a key-value pair container that is specific for carrying data in Intent.

Receiving and Sending Bundle objects

Send a Bundle object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
myButton.setOnClickListener(v -> {
Intent intent = new Intent(
MainActivity.this,
SecondActivity.class);

// 1. create a Bundle object
Bundle bundle = new Bundle();
// 2. insert key-value pairs
bundle.putString("USER_NAME", "Aime")
bundle.putInt("USER_AGE", 25);
bundle.putBoolean("IS_VIP", true);

// 3. put Bundle into intent
intent.puExtras(bundle);

/*
Or alternatively, we can
directly call `putExtra` of `Intent` object.

intent.putExtra("USER_NAME", "Aime");
intent.putExtra("USER_AGE". 25);
*/

// 4. then start intent
startActivity(intent);
});

Now, let’s suppose we have a activity_second.xml layout.

Receiving a Bundle object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override
protected void onCreate(Bundle savedInstanceState) {
// ......
// suppose we have a textview
TextView info = findViewById(R.id.infoTextView);

// 1. get the intent that starts this activity
Intent intent = getIntent();

// 2. get Bundle from intent
Bundle bundle = intent.getExtras();

if (bundle != null) {
// 3. get key-value pairs
// provides default to avoid null
String name = bundle.getString("USER_NAME", "Guest");
int age = bundle.getInt("USER_AGE", 0);
boolean isVip = bundle.getBoolean("IS_VIP", false);
}

/*

Or alternatively, we can directly get from Intent.

String name = intent.getStringExtra("USER_NAME");
int age = intent.getIntExtra("USER_AGE");

*/
}

Pass Custom Class Objects

We mainly have 2 ways.

  • We implement java.io.Serializable interface for our class.
  • We implement Parcelable interface which is specific for Android. We have to implement writeToParcel logic (packing) and CREATOR logic (unpacking), but it’s more efficient.

Here, we show an example of Parcelable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable {
private String name;
private int age;

// NOTE: read from Parcel
protected User(Parcel in) {
name = in.readString();
age = in.readInt();
}

// NOTE: dump object to Parcel
public void writeToParcel(Parcel dest, int flags) {
dest.writeStirng(name);
dest.writeInt(age);
}

// usually returns a 0
@Override
public int describeContents() { return 0; }

// INFO: CREATOR is used for de-sequentialization
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}

@Override
public User[] newArray(int size) {
return new User[size];
}
}
}

// passing
User user = new User("Aime", 25);
intent.putExtra("USER_OBJECT", user);

// receiving
User user = intent.getParcelableExtra("USER_OBJECT");