huazi

huazi

"Notes on 'Android Development Art Exploration' - Chapter 2"

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:

  1. Static members and singleton patterns are completely ineffective.
  2. Thread synchronization mechanisms are completely ineffective.
  3. The reliability of SharePreferences decreases.
  4. 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.

  1. Static member variables belong to the class, not the object, so they do not participate in the serialization process.
  2. 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:

  1. 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.
  2. 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 Workflow.png

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#

  1. Bundle
    Bundle implements the Parcelable interface, so it is convenient for transmission between processes.

  2. 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.

  3. 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:
    Messenger Working Principle.png

  4. 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.

  5. 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.

  1. 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#

NameAdvantagesDisadvantagesApplicable Scenarios
BundleSimple and easy to useCan only transmit data types supported by BundleInter-process communication between components
File SharingSimple and easy to useNot suitable for high-concurrency scenarios, cannot achieve real-time communication between processesNo concurrent access scenarios, exchanging simple data with low real-time requirements
AIDLPowerful, supports one-to-many concurrent communication, supports real-time communicationSlightly more complex to use, need to handle thread synchronization properlyOne-to-many communication with RPC requirements
MessengerModerate functionality, supports one-to-many serial communication, supports real-time communicationCannot handle high-concurrency scenarios well, does not support RPC, data is transmitted through messages, can only transmit data types supported by BundleLow-concurrency one-to-many real-time communication, no RPC requirements or RPC requirements without result
ContentProviderPowerful in data source access, supports one-to-many concurrent data sharing, can be extended through Call methodsCan be understood as a constrained AIDL, mainly provides CRUD for data sourcesOne-to-many inter-process data sharing
SocketPowerful, can transmit byte streams through the network, supports one-to-many concurrent real-time communicationSlightly more complex in implementation details, does not support direct RPCNetwork data exchange
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.