title: Notes on "Android Development Art Exploration" - Chapter 2
date: 2017-05-21 11:32:59
tags:
- Android
- Binder
- IPC
- Inter-Process Communication
- Notes
categories: - Android
- Notes
IPC stands for Inter-Process Communication, which refers to the process of communication between two processes.
A thread is the smallest unit of CPU scheduling and is a limited system resource. A process generally refers to an execution unit, and a process can contain multiple threads. A process can have only one thread, which is the main thread.
There are two types of multi-processes. The first case is when an application needs to use multi-threading mode for implementation due to certain reasons, and the second case is when the current application needs to obtain data from other applications.
The only way to use multiple processes in Android is to specify the android attribute for the four major components in AndroidManifest. There is no other way. The adb shell ps
command can be used to view process information.
Processes starting with :
are private processes of the current application, and components of other applications cannot run in the same process as it;
Processes not starting with :
are global processes, and other applications can run in the same process with it through the ShareUID method. The system assigns a unique UID to each application, and applications with the same UID can share data.
Each process in Android is assigned an independent virtual machine, and each virtual machine is allocated a different address space. The four major components running in different processes will fail to share data through memory.
Multiple processes can cause the following problems:
- Static members and singleton patterns are completely ineffective.
- Thread synchronization mechanisms are completely ineffective.
- The reliability of SharePreferences decreases.
- Application will be created multiple times.
For 1 and 2, it is the same problem. Locking objects or locking global classes cannot guarantee thread synchronization because different processes do not lock the same object.
SharePreferences does not support simultaneous write operations by two processes because SharePreferences is implemented through reading and writing XML files, and concurrent reading and writing may cause problems.
Components running in different processes belong to two different virtual machines and applications. Each time a process is started, the Application onCreate will be executed.
Basic Concepts of IPC#
The basic concepts of IPC mainly include three aspects: Serializable interface, Parcelable interface, and Binder. Serializable and Parcelable can complete the process of object serialization, and Serializable and Parcelable need to be used when transferring data through Intent and Binder.
Serializable Interface#
Serializable is a serialization interface provided in Java, which provides standard serialization and deserialization operations for objects.
serialVersionUID
is used to assist the serialization and deserialization process. In principle, the serialVersionUID
in the serialized data should be the same as the serialVersionUID
of the current class in order to be deserialized normally. When serializing, the system will write the serialVersionUID
of the current class into the serialized file. When deserializing, the system checks whether the serialVersionUID
in the file is the same as the serialVersionUID
of the current class. If they are consistent, deserialization can be performed normally; otherwise, deserialization cannot be performed normally. Generally, serialVersionUID
needs to be specified manually. If not specified, the hash value of the current class will be recalculated when the current class is changed, and it will be assigned to serialVersionUID
.
- Static member variables belong to the class, not the object, so they do not participate in the serialization process.
- Variables marked with
transient
do not participate in the serialization process.
Parcelable#
Parcelable is a new serialization method provided by Android, and it is also an interface. The serialization function is completed by writeToParcel
. Intent, Bundle, and Bitmap all implement this interface and can be directly serialized.
Serializable is a Java interface, which is simple to use but has a high cost. Serialization and deserialization require a lot of I/O operations.
Parcelable is more troublesome to use but has high efficiency, so it is recommended to use it.
When storing serialized objects in devices or transmitting objects through networks, it is recommended to use Serializable.
Binder#
In Android development, Binder is mainly used in Service, AIDL, and Messenger. The Binder in a regular Service does not involve inter-process communication. Messenger is based on AIDL. The unique identifier of Binder is generally represented by the class name of the current Binder.
Binder is the bridge between ServiceManager and various Managers (ActivityManager, WindowManager, etc.) and the corresponding ManagerService.
System-generated Binder class parameter parsing:
- DESCRIPTOR: The unique representation of Binder, generally represented by the class name of the current Binder.
- asInterface(android.os.IBinder obj): Used to convert the Binder object of the server into the AIDL interface type object required by the client. This conversion is inter-process. If the client and server are in the same process, this method returns the server's Stub object itself; otherwise, it returns the system-wrapped Stub.proxy object.
- adBinder: Returns the current Binder object.
- onTransact: Runs in the Binder thread pool of the server. When the client initiates a request, the remote request will be handed over to this method for processing.
Two points to note about the working mechanism of Binder:
- When the client initiates a remote request, the current thread will be suspended until the server process returns data. This is a time-consuming operation.
- The server Binder method runs in the Binder thread pool, so the Binder method should be implemented in a synchronous manner regardless of whether it is time-consuming or not.
Binder's working mechanism diagram:
Binder runs on the server. If the server process terminates due to certain reasons, remote calls will fail. Binder provides two methods, linkToDeath
and unLinkToDeath
, to set the death proxy of Binder.
The death of Binder can also be judged by the isBinderAlive
method of Binder.
IPC Methods in Android#
-
Bundle
Bundle implements the Parcelable interface, so it is convenient for transmission between processes. -
File Sharing
Two processes exchange data by reading and writing the same file. Concurrent reading and writing may cause problems, so it is best to avoid concurrent writing and consider using thread synchronization to limit the write operations of multiple threads.
SharePreferences is also a type of file. The system has a caching strategy for reading and writing, but it is unreliable in multi-process mode. -
Messenger
Messenger is a lightweight IPC, and its underlying implementation is AIDL. Messenger processes client messages in a serialized manner. It is mainly used for message transmission.
Working principle diagram:
-
AIDL
Using AIDL for inter-process communication involves two aspects: the server and the client. The general process is as follows: the server first creates a Service to listen for client requests, then creates an AIDL file to declare the interface exposed to the client, and then implements this AIDL interface in the Service. The client binds to the server's Service, and after successful binding, converts the Binder object returned by the server into the type of the AIDL interface, and then calls the AIDL method. -
ContentProvider
ContentProvider is a method specifically designed for data sharing between different applications in Android, and its underlying implementation is Binder. ContentProvider does not have requirements for underlying data storage.
First, the Provider needs to be registered, and android:authorities
is the unique identifier of the Provider, which is used to access the Provider.
The onCreate of the Provider runs on the main thread, and other methods run in the Binder thread pool. query, update, insert, and delete can be accessed concurrently, so thread synchronization should be done internally.
- Socket
Socket is a concept of network communication.
- TCP is a connection-oriented protocol that provides stable bidirectional communication.
- UDP is a connectionless protocol that provides unstable unidirectional communication, but it can also provide bidirectional communication. It has better efficiency but cannot guarantee correct transmission.
Binder Connection Pool#
The general process of using AIDL is as follows: first, create a Service and an AIDL interface, then create a class that inherits from the Stub class in the AIDL interface and implement the abstract methods in the Stub class, return an object of this class in the onBinder method of the Service, and then the client can bind to the server's Service and establish a connection. After the connection is established, remote methods of the server can be accessed.
When the project is large in scale, it is not correct to create many Services. Services are system resources, and having too many Services will make the application appear heavy. Therefore, it is best to put all AIDLs in the same Service for management.
The Binder connection pool is used to forward Binder requests of each business module to a remote Service for execution, avoiding the process of repeatedly creating Services.
BinderPool greatly improves the development efficiency of AIDL and avoids creating a large number of Services. It is recommended to introduce BinderPool in AIDL.
Choosing the Right IPC Method#
Name | Advantages | Disadvantages | Applicable Scenarios |
---|---|---|---|
Bundle | Simple and easy to use | Can only transmit data types supported by Bundle | Inter-process communication between components |
File Sharing | Simple and easy to use | Not suitable for high-concurrency scenarios, cannot achieve real-time communication between processes | No concurrent access scenarios, exchanging simple data with low real-time requirements |
AIDL | Powerful, supports one-to-many concurrent communication, supports real-time communication | Slightly more complex to use, need to handle thread synchronization properly | One-to-many communication with RPC requirements |
Messenger | Moderate functionality, supports one-to-many serial communication, supports real-time communication | Cannot handle high-concurrency scenarios well, does not support RPC, data is transmitted through messages, can only transmit data types supported by Bundle | Low-concurrency one-to-many real-time communication, no RPC requirements or RPC requirements without result |
ContentProvider | Powerful in data source access, supports one-to-many concurrent data sharing, can be extended through Call methods | Can be understood as a constrained AIDL, mainly provides CRUD for data sources | One-to-many inter-process data sharing |
Socket | Powerful, can transmit byte streams through the network, supports one-to-many concurrent real-time communication | Slightly more complex in implementation details, does not support direct RPC | Network data exchange |