SoFunction
Updated on 2025-04-11

Analysis of Intent Components in Android from Source Code

We know that Intent is mainly used to activate several major components of Android, so how do it activate it? Can I carry java objects when activated? Why do I need to serialize the object before I can pass it?

1. Intent official website explanation
Intent can be used by startActivity to load the Activity, or it can be sent to the specified BroadReceiver component by broadcastIntent.
Or be communicated with the background service by startService or bingService.
The main function of Intent is to load the Activity, such as the glue between the Activity.
Intent data structure:

  • action: the action to be performed; (for example: ACTION_CALL creates a call activity; ACTION_BATTERY_LOW issues a broadcast warning that the battery is low,)
  • data: The data to be used (Uri);
  • category: Information about the target component;
  • component: the class name of the target component;
  • extras: This is the Bundle data.

Intent parsing:

  • An explicit Intent specifies the class name of the target component, that is, component, then the target component is known and does not require parsing;
  • Implicit Intent, the target component is not specified, or does not know or care about who will receive the Intent, Android needs to parse and find the target component by itself.

Implicit Intent parsing method:

1. All <intent-filter> and the Intent defined therein;
2. Search for the component that can handle this Intent through the PackageManager (get the application package installed on the current device). Match three variables Action, type, and category to find them.
2. Simple explanation:
Intent can activate three major components of Andorid: Activity, Service and BroadcastReceiver. When using Intent, you generally need to explicitly specify the target component. If not specified, you need to parse it based on the three values ​​of action, type, and category that comes with Intent to find components that can be processed.

3. Question: How to switch components in Intent and the specific process?
1. Basic method: (Take the startup of the Activity as an example)

Intent i = new Intent(, );
startActivity(i);

2. Instantiate the Intent:

/**
 * Create an Intent, directly specify the ** component class name** to be activated by the Intent, without relying on the ** system to parse the appropriate class to handle the intent
 * @param packageContext The context object to execute this intent
 * @param cls intent component class name to activate
 */
public Intent(Context packageContext, Class cls) {
//Create a component and assign it to the Component member of the Intent  mComponent = new ComponentName(packageContext, cls);
}

3. Start Activity

startActivity(i) -&gt;
startActivity(Intent intent, @Nullable Bundle options)-&gt;
startActivityForResult(intent, -1, options)


/**
 *startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options)
 * Load an Activity and get the result
 * @param intent The intent to be started.
 * @param requestCode If it is greater than 0, it will be returned, and the view will be displayed only after the return value is successfully returned.
 * @param options Other information.
 */
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) { //If there is no parent activity; Instrumentation is used to interact with the AndroidManifest file on the program guide list.   ar =
  (this, (), mToken, this,intent, requestCode, options); //Execute the startActivity command..... 
} else { //If there is a parent activity   if (options != null) {
     (this, intent, requestCode, options);
   } .....
}

4. Execute the startActivity command core code:
The task of starting the Activity is handed over to the underlying ActivityManagerNative.

(); // Process the bundle data in the intent for the underlying processing(); //Prepare to leave the application process and enter the ActivityManagerService process (meaning that the data of the bundle must be passed between processes)int result = ().startActivity(whoThread,   
(), intent,
(()),
token, target != null ?  : null,
requestCode, 0, null, options); //Calling the system's activity manager service to start a new activity.  Consider that if it is an explicit Intent, directly find the corresponding component class (here is the Activity component); if it is an implicit Intent, if it is a specified target component class name, then automatically go to Application->system to search for the appropriate component to handle it.//todo: The specific system-level code will be analyzed next time

4. Core question: Why can’t Intent pass objects directly between components and pass the serialization mechanism?
According to the above code, you can see that when the Intent starts other components, it will leave the current application process and enter the ActivityManagerService process (()), which means that the data carried by the Intent must be transmitted between different processes. First of all, we know that Android is based on Linux system, and Java objects between different processes cannot be transmitted, so we need to serialize the objects here to realize the transmission of objects between the application process and the ActivityManagerService process.
Both Parcel or Serializable can serialize objects. Among them, Serializable is easy to use, but its performance is not as good as that of Parcel containers, which is also an interface specially launched by Android for inter-process communication, etc.

Additional knowledge:
Between different processes, regular data types can be directly passed, such as integers. Taking the passing string as an example, to pass from process A to process B, you just need to open up the same size space in the memory area of ​​process B and then copy it.
However, objects cannot be directly passed across processes. Even if the member variable value can be passed, the member method cannot be passed. At this time, if the B process wants to call the member method, an error occurs.
Specific methods for passing objects:
1. In process A, package the non-default attributes in the class and the unique flags of the class into a package (this is called serialization);
2. Pass this package to process B;
3. After process B receives the package, it creates the class based on the class's unique flag (java reflection mechanism);
4. Then update the passed attribute to the class object.
In this way, process A and process B contain two exactly the same class objects.

5. How to implement object delivery intent?
Object implements Serializable {...};(Key, Object);
Object implements Parcelable {...} ; (Key, Object);
Serializable interface: This is Java's serialization technology, which serializes Java objects into binary files. Let the object implement the Serializable interface and use ObjectInputStream and ObjectOutputStream to read and write objects.
Parcelable interface: This is a container provided by Android to encapsulate data. The encapsulated data can be passed through Intent or IPC. Only basic types and classes that implement the Parcelable interface can be put into Parcel.
6. Serializable interface - Java
It belongs to the Java serialization mechanism: Just let the java class implement the interface and mark the class serializable without implementing any methods.

class Person implements Serializable {...}
Person per = new Person();
("person", per); // Pass the reference to the Person object
Person mPerson = (Person)getIntent().**getSerializableExtra**("person");

Note: If the serialized class Person here contains references to other classes (such as PersonInfo), such as:

class Person implements Serializable {
   PersonInf**o info;
}

Then the referenced class must also be serializable, that is, implementing the Serializable interface. Because Person objects will also serialize member variables during serialization.

7. Parcelable interface - Android
Here is a brief introduction to the reason - How to use Parcel in Android to implement object delivery.
First of all, you need to understand the Parcel container in Android.

Parcel is a container that stores messages (data or object references) that can be transmitted through IBindler.
Mainly used for lightweight, high-performance IPC interprocess communication. In Android, a "process" is a standard Linux process. Generally speaking, one process cannot access the memory area of ​​another process. Through Parcel, the Android system will decompose objects into serializable and deserialized, thereby realizing inter-process communication.
However, Parcel can also be used for in-process communication, mainly implementing the transfer of data between different components of the application. For example, we can use Intent to encapsulate Parcel objects to pass between activities.
Simply put, the Parcel container implements in-process communication and inter-process communication, and can also implement remote calls.

Specific methods for passing objects between components:

Let the class to which the object to be passed implement the Parcelable interface;
Implement the describeContents method;
Implement the abstract method writeToParcel, which is used to obtain the current state of the object and write it to a Parcel container;
Add a static domain CREATOR to the target class, which is an object that implements the interface;
Add a constructor with a parameter as a Parcel object, and CREATOR will call this constructor to re-model our object.
question:
Why do you need to create a Parcelable interface if you already have the Java Serializable interface?
performance
Although Parcelable is a little more complicated to use, it performs better.

Parcelable restrictions:

It is not ideal when using Parcelable to pass image Bitmap, although Bitmap also implements the Parcelable interface. The better method is transmission
Parcelable cannot be used as a regular serialized storage, because the Android version is different, and the specific implementation methods of Parcelable are not exactly the same, which may lead to the inability to read Parcel data.