preface

This post has been posted on my Github blog. Welcome to my humble abode:

My GIthub blog

Study list:

  • Basic concepts of IPC
  • The concept of multiprocess and multithreading
  • Serialization mechanism and Binder in Android
  • IPC mode in Android
  • Binder connection pool concept and application
  • Advantages and disadvantages of various IPC

1. Why studyIPC?

IPC is short for Inter-process Communication. It refers to the Process of data exchange between two processes.

Some readers may be wondering, “What is a process? What is a thread? What’s the difference between multi-processing and multi-threading?”

  • Process: The smallest unit of resource allocation, usually a unit of execution. On PCS and mobile devices, it refers to a program or application.
  • Thread: The smallest unit of CPU scheduling. Threads are a finite system resource.

Relationship: A process can contain multiple threads, that is, multiple tasks can be performed simultaneously on an application.

  • Main thread (UI thread) : UI operations
  • Finite child threads: Time-consuming operation

Note: Do not do a large number of time-consuming operations on the main thread. This will result in ANR (application non-response). Solution: Put time-consuming tasks in threads.

IPC is not unique to Android. The most distinctive IPC approach in Android is Binder. All the knowledge involved in daily development: AIDL, plugins, componentization, etc. Therefore, IPC is very important.

Two. Induction of core knowledge points

2.1 AndroidMulti-process mode in

Q1: How to enable multi-threading:

  • Often used inAndroidMenifestTo specify properties for the four major componentsandroid:process

Precess naming rules:

  • Default process: If this property is not specified, it runs in the default process whose process name is the package name.
  • The process whose name starts with: indicates that the process name is preceded by the package name. The process belongs to the current application private process
  • Fully named process: belongs to the global process, other applications can run in the same process with it through the ShareUID mode (need the same ShareUID and signature).
  • (uncommon) Fork a new process in the native layer via JNI.

Q2: Operation mechanism of multi-process mode:

Andoird assigns a separate VIRTUAL machine to each process. Different virtual machines have different address Spaces for memory allocation, which also results in multiple copies of the same object being accessed by different virtual machines.

Four aspects of the problem:

  • Static variable and singleton mode failure -> Cause: Multiple copies of the same object are generated when accessed from different virtual machines.
  • Thread synchronization mechanism failed –> Cause: Threads cannot synchronize due to different memory.
  • The reliability of SharedPreference deteriorates –> Cause: The underlying layer is implemented by reading and writing XML files, causing concurrency problems.
  • Application is created multiple times. Cause: The Android system assigns independent VMS to new processes, which means that the Application is restarted once.

2.2 IPCBasic concept

Here we mainly introduce three aspects:

  • Serializable
  • Parcelable
  • Binder

Only by being familiar with these three aspects can we better understand the various ways of IPC

2.2.1 What is serialization

  • Serialization means converting an object into a state that can be stored or transferred. Serialized objects can be transferred over the network or stored locally.
  • Application scenario: YesIntentandBinderTransmission etc.Class objectThe object must be serialized.
  • Two ways: implementationSerializable/ParcelableInterface.

2.2.2 Serializableinterface

Java provides a serialization interface that is relatively simple to use:

  • Entity class implementationSerializable
  • Manually set/automatically generated by the systemserialVersionUID
//Serializable Demo
public class Person implements Serializable{
    private static final long serialVersionUID = 7382351359868556980L;
    private String name;
    private int age;
    public int getAge(a) {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName(a) {
        return name;
    }
    public void setName(String name) {
        this.name = name; }}Copy the code

Pay special attention to the serialVersionUID:

  • Meaning:SerializableInterface to assist in serialization and deserialization processes.
  • Note: in principle, in serialized dataserialVersionUIDTo match the current classserialVersionUID The sameTo properly serialize. When a class changes unconventionally (modifiedThe name of the class/ Changed the memberType of variable), serialization failed.

2.2.3 Parcelableinterface

Serialization is the Android serialization interface, when using, the class needs to achieve the following points:

  • implementationParcelableinterface
  • The content description
  • Serialization method
  • Deserialization method

public class User implements Parcelable {

    public int userId;
    public String userName;
    public boolean isMale;

    public Book book;

    public User(a) {}
    public User(int userId, String userName, boolean isMale) {
        this.userId = userId;
        this.userName = userName;
        this.isMale = isMale;
    }
 // Return 0 public int describeContents(a) { return 0; } Copy the code

/ / the serialization public void writeToParcel(Parcel out, int flags) { out.writeInt(userId); out.writeString(userName); out.writeInt(isMale ? 1 : 0); out.writeParcelable(book, 0); } // deserialize public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() { // Create the original object from the serialized object public User createFromParcel(Parcel in) { return new User(in); } public User[] newArray(int size) { return newUser[size]; }}; // Create the original object from the serialized object private User(Parcel in) { userId = in.readInt(); userName = in.readString(); isMale = in.readInt() == 1; book = in.readParcelable(Thread.currentThread().getContextClassLoader()); } @Override public String toString(a) { return String.format("User:{userId:%s, userName:%s, isMale:%s}, with child:{%s}", userId, userName, isMale, book); } }

2.2.4 Comparison of Serializable and Parcelable interfaces

Serializableinterface Parcelableinterface
platform Java Andorid
Serialization principle To convert an object into a state that can be stored or transferred An object is decomposed, and each part of the decomposed object is passed a supported data type
The advantages and disadvantages Advantages: Simple to use Disadvantages: high overhead (because a large number of I/O operations are required) Advantages: high efficiency Disadvantages: troublesome to use
Usage scenarios Serialize objects to storage devices or transfer them over the network Mainly used for memory serialization

2.2.5 Binder

Q1: What is a Binder?

  • From an API point of view: is a class, implementationIBinderInterface.
  • From the IPC point of view: YesAndroidA cross-process communication mode in.
  • From a Framework perspective: YesServiceManager, connecting various kinds ofManagerAnd the correspondingManagerServiceThe bridge.
  • From the application layer: the medium through which clients and servers communicate. The client can obtain services or data provided by the server.

Q2:Android is designed based on the Linux kernel. Instead of using pipes, message queues, shared memory, semaphores, sockets and other IPC communication means as the main IPC mode of Android, Binder mechanisms are added.

A1: High transmission efficiency and operability

The transmission efficiency is mainly affected by the number of memory copies. The smaller the number of memory copies, the higher the transmission rate. Comparison of several data transmission methods

way Copy number Operation difficulty
Binder 1 Simple and easy
The message queue 2 Simple and easy
Socket 2 Simple and easy
The pipe 2 Simple and easy
The Shared memory 0 complex

Analysis from the perspective of Android process architecture: For message queues, sockets and pipes, data is first copied from the sender’s cache to the cache created by the kernel, and then copied from the kernel cache to the receiver’s cache, twice in total, as shown in the figure:

Data copy of message queues, sockets, and pipes

Binder: Data is copied from the sender’s cache to the kernel’s cache, and the receiver’s cache and the kernel’s cache are mapped to the same physical address, saving a data copy process

A2: Convenient implementation of C/S architecture

All IPC methods of Linux are not based on C/S architecture except Socket, which is mainly used for communication between networks and has low transmission efficiency. Binder based on C/S architecture, the Server and Client are relatively independent, providing high stability.

A3: High security

The receiver of traditional Linux IPC cannot obtain the reliable UID/PID of the process of the other party, so it cannot identify the other party. The Binder mechanism assigns a UID/PID to each process and checks its validity when it communicates with the Binder.

Q3: What four roles are defined by the Binder framework?

A1:Server&Client

Server & client. Client-server communication is performed over infrastructure provided by Binder drivers and Service Manager.

A2:ServiceManager:

The manager of the service translates the Binder name into a reference to the Binder in the Client so that the Client can get a reference to the Binder entity in the Server through the Binder name.

ServiceManager working mechanism

A3: Binder

  • It has nothing to do with the hardware device. It works in the same way as the device driver, working in kernel mode.
  • provideopen(),mmap(),poll(),ioctl()Etc standard file operation.
  • To drive a character in a devicemiscThe device is registered in the device directory/devThe user passes/dev/binderAccess it.
  • Responsible between processesbinderCommunication establishment, transmission, count management and data transmission interaction and other low-level support.
  • A set of interface protocols is defined between drivers and applicationsioctl()Interface implementation, due toioctl()Flexible, convenient, and able to implement write before read in one call to meet synchronous interaction, so it is not necessary to call separatelywrite()andread()Interface.
  • Its code is locatedlinuxThe directorydrivers/misc/binder.cIn the.

Ioctl (Input /output Control) is a system call dedicated to device input and output operations. The call passes in a request code related to the device. The function of the system call depends entirely on the request code

Q4: How does Binder work

  • Server side: One is created on the server sideBinderObject, and an internal one is openedthreadUsed to receiveBinderThe message sent by the driver is executed after receiving the messageonTranscat()And execute different server-side code according to the parameters.
  • BinderDriver: Successfully created on the serverBinderAfter the object,BinderThe driver also creates onemRemoteObject (alsoBinderClass, which the client can calltranscat()Can send a message to the server.
  • Client: The client wants to accessBinderTo obtain the remote serviceBinderObjects in theBinder driver layerThe correspondingmRemoteReferences. When it get tomRemoteObject, can be called accordinglyBinderObject method exposed to the client.
Working mechanism of Binder

When a remote request is made, the Client hangs and does not wake up until data is returned

Q5: What if the server process terminates unexpectedly, causing the Binder to die?

After the client binds the remote service successfully, we set up the death proxy for Binder. When Binder dies, we will be notified and re-initiate the connection request.

private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient(){
@Override
public void binderDied(a){
if(mBookManager == null) {return;
}
mBookManager.asBinder().unlinkToDeath(mDeathRecipient,0);
mBookManager = null;
// TODO: rebind the remote Service}}Copy the code
mService = IBookManager.Stub.asInterface(binder);
binder.linkToDeath(mDeathRecipient,0);
Copy the code

2.3 AndroidIn theIPCway

There are many different ways of IPC in Android, but all are essentially built with Binder

IPC mode in Android

2.3.1 Bundle

  • Principle:BundleThe underlying implementationParcelableInterface, which can be easily transferred between different processes.
  • Note: Data types not supported by the Bundle cannot be passed in the process.
  • Test: How do I pass the result of A calculation to PROCESS B that is not of the data type supported by the Bundle?

  • A: Move the computation done in process A to A Service in process B, thus successfully avoiding communication problems between processes.

  • IntentandBundleThe difference and connection between:
  • IntentThe bottom layer is actually throughBundleTo transfer data
  • Easy to use:IntentIt’s easy,BundleMore complicated
  • IntentFor data transfer,bundleDesigned to access data

2.3.2 File Sharing

  • Concept: Two processes exchange data by reading/writing the same file. For example, process A writes data to A file, and process B reads the file to get data.
  • Application scenario: Processes that do not have high requirements on data synchronization communicate with each other and properly handle concurrent read/write problems.
  • Special circumstances:SharedPreferencesIt is not recommended for file storage. Because the systemSharedPreferencesThe read/write of the file has a cache policy, i.e. there is a copy of the file in memoryThe cacheTherefore, in multi-process mode, its read/write will become unreliable and even lose data.

2.3.3 AIDL

2.3.3.1 concept

Android Interface Definition Language (AIDL) If you want to call a method on an object in another process, you can use AIDL to generate serializable parameters. AIDL generates a proxy class for a server object through which the client implements indirect calls to the methods on the server object.

2.3.3.2 Supported Data Types
  • Basic data types
  • StringandCharSequence

If you want to know the difference between a String and a CharSequence, check out this article: The difference between a String and a CharSequence

  • ArrayList,HashMapAnd every element in it can beAIDLsupport
  • implementationParcelableObject of interface
  • allAIDLThe interface itself

Note: In, out, or inout, parameters of any type other than the basic data type must be marked with direction to indicate the flow of data in cross-process communication.

2.3.3.3 twoAIDLfile
  • Used to defineParcelableObject for otherAIDLFiles useAIDLData types that are not supported by default.
  • Used to define method interfaces for use by the system to accomplish cross-process communication.

Note:

  • The custom ofParcelableobjectMust betheJavaFile and customAIDLFile explicitimportCome in, whether it’s in the same bag or not.
  • AIDLThe file is customizedParcelableThe object,Must beCreate a new one with the same nameAIDLFile in which it is declared asParcelableType.
2.3.3.4 Essence, key classes and methods

A: The essence of the system is that it provides a set of tools that can be quickly implemented with Binder.

B: What are the key classes and methods?

  • AIDLinterfaceInherited:IInterface.
  • Stubclass:BinderImplementation class, through which the server provides services.
  • Proxy class: the server’s local Proxy through which the client invokes the server’s methods.
  • asInterface(): a client call that returns the serverBinderObject to what the client needsAIDLInterface type object.

Return object:

  • If the client and server are in the same process, return directlyStubThe object itself;
  • Otherwise, the system package is returnedStub.proxyObject.
  • asBinder(): Return proxyProxytheBinderObject.
  • onTransact(): Runs the serverBinderIn a thread pool, when a client initiates a cross-process request, the remote request is processed by this method after being wrapped by the underlying system.
  • transact(): Runs on the client and suspends the current thread when the client initiates a remote request. Then call the server sideonTransact()The current thread does not resume execution until the remote request returns.
How AIDL works
2.3.3.5 Implementation method

If interested readers want to learn more about the specific AIDL process for implementing IPC, I share an article: Android Cross-process Communication (IPC) : Using AIDL

A. Server:

  • Create a **aidlThe file * *;
  • To create aServiceTo realizeAIDLThe interface functions are exposedAIDLInterface.

B. Client:

  • throughbindServiceBind the serverService;
  • After the binding is successful, the server is returnedBinderobjectconversionintoAIDLThe type to which the interface belongs, and then the correspondingAIDLMethod in.

Summary: A Service on the server provides Binder objects to a particular client process bound to it. The client uses the static method asInterface() of the AIDL interface to convert Binder objects into AIDL proxy objects that can be used to make remote invocation requests.

2.3.3.6 PossibleANRThe circumstances of

A. Client:

  • The method that calls the server side is run on the server sideBinderThread pool, ifThe main threadThe method is calledTime consumingIn addition, the client thread will block for a long time, easily causing the clientANR.
  • inonServiceConnected()andonServiceDisconnected()In direct call server time-consuming methods, easy to cause the clientANR.

B. Server:

  • The server-side methods themselves run on the server-sideBinderthreadIn which time consuming operations can be performed, whileNo need to open child thread **.
  • Callback clientListenerThe method ofIt runs on the client sideBinderIn a thread, if the called method executes aTime consumingThe task easily leads to the serverANR.

Solution to the high performance drain caused by frequent client calls to server methods: Implement observer mode.

That is, when the data that the client cares about changes, the server notifies the client to perform corresponding service processing.

2.3.3.7 Failed to deregister
  • The reason:BinderObject transfer is actually done through serialization and deserialization, i.eBinderThe object that passes the client overTo convertAnd generate a new object, although in the process of registration and reconciliation using the same client to pass the object, but afterBinderWhen passed to the server, two different objects are generated. In addition, the same client object that is transferred multiple times across processes is generated on the server sidedifferentObject, but they are at the bottomBinderThe object isThe same.
  • Solution: When the client unregisters, iterate over all of the serverListener, find the settlement registrationListenerHave the sameBinderObject serverListener, delete it.

RemoteCallBackList: An Android interface that removes cross-process Listeners. Its internal automatic thread synchronization function.

2.3.4 Messager

Q1. What is a Messager?

A1: Messager is a lightweight IPC scheme that allows Message objects to be passed between different processes.

Messenger.send(Message);
Copy the code

Q2: What are the characteristics?

  • The underlying implementation isAIDL, that is, theAIDLEncapsulation is carried out to facilitate inter-process communication.
  • The server handles client requests in a serial manner without concurrent execution, so there is no need to consider the problem of thread synchronization.
  • Can be passed in different processesMessageObject,MessagerThe supported data types areMessengeSupported data types.

Messenge supports the following data types:

  • arg1,arg2,whatFields:intType of data
  • objFields:ObjectObject, supported by the systemParcelableobject
  • setData:Bundleobject
  • There are two constructors that receive, respectivelyHandlerThe objects andBinderObject.

Q3: Implementation method:

Readers interested in using Messenger in detail can check out this article: IPC-Messenger Usage Examples

A1: server:

  • To create aServiceUsed to provide services;
  • Create one of themHandlerUsed forreceiveThis is from the client processdata;
  • usingHandlerTo create aMessengerObject;
  • inServicetheonBind()In returnMessengerThe correspondingBinderObject.

A2: Client:

  • BindService binds the Service on the server.

  • A Messenger is created from the IBinder object returned by the binding, which in turn sends Message data to the server-side process. (So far only one-way communication has been completed)

  • Create a Handler on the client side and create a Messenger from it, which is passed to the server-side process via the **replyTo field ** of Message. The server reads Message to get the Messenger object, which in turn passes data to the client process. (Complete two-way communication)

    Messenger communication

Q4: faults:

  • The main function is transmissionMessage, difficult to implement remote method calls.
  • Messages sent by clients are processed in serial mode, which is not suitable for high concurrency scenarios.

Solution: Use AIDL to handle IPC in high concurrency scenarios

2.3.5 ContentProvider

ContentProvider is a special way to share data between different applications provided by Android. Binder is also used to implement the underlying.

  • In addition toonCreate()It’s running in the UI thread, and everything elsequery(),update(),insert(),delete()andgetType()Both run inBinderThread pool.
  • CRUDThe four operations have multi-threaded concurrent access, so it is important to do thread synchronization within the method.
  • aSQLiteDatabaseInternal database operations are synchronized, but multipleSQLiteDatabaseCannot synchronize between.

2.3.6 Socket

Sockets can communicate not only across processes, but also across devices

Q1: What is the type of use?

  • Stream socket: based onTCPProtocol, which provides reliable byte stream service in a stream manner.
  • Data flow socket: based onUDPProtocol that uses data packets to provide the data packet sending service.

Q2: What is the implementation method?

A1: server:

  • To create aService, created in the threadTCPService, listening to the corresponding port waiting for the client connection request;
  • When connecting to the client, a new one is generatedSocketObject, which can be used for data transmission with the client;
  • When disconnected from the client, close the correspondingSocketAnd terminates the thread.

A2: Client:

  • Start a thread and passSocketMake a connection request;
  • After the connection is successful, the server message is read.
  • Disconnect and close the connectionSocket.

2.3.7 Comparison of advantages and disadvantages

The name of the advantages disadvantages Applicable scenario
Bundle Simple and easy to use Can only transferBundleSupported data types Interprocess communication between the four components
File sharing Simple and easy to use It is not suitable for high concurrency scenarios and cannot achieve instant communication between processes No concurrent access, simple data exchange and low real-time
AIDL Supports one-to-many concurrency and real-time communication It’s a little more complicated to use and needs to handle thread synchronization One to many and there areRPCdemand
Messenger Supports one-to-many serial communication Does not handle high concurrency well, not supportedRPC, can only be transmittedBundleSupported data types Low concurrency one-to-many
ContentProvider Supports one-to-many concurrent data sharing Can be understood as constrainedAIDL Data sharing between one-to-many processes
Socket Supports one-to-many concurrent data sharing Cumbersome implementation details Network data exchange

2.4 BinderThe connection pool

If there are multiple business modules that require AIDL for IPC, specific AIDL files need to be created for each module, and the corresponding services will be numerous. It is inevitable that there will be serious system resource consumption and excessive application heavyweight problems. Therefore, Binder connection pools are needed to avoid duplicate Service creation by uniformly forwarding Binder requests from each business module to a remote Service for execution.

Q1: How does it work?

Each business module creates and implements its own AIDL interface, and then provides its own unique identity and corresponding Binder objects to the server. The server only needs one Service. The server provides a queryBinder interface, which returns corresponding Binder images according to the characteristics of business modules. After different business modules get the required Binder objects, they can call remote methods.

Working principle of Binder connection pool

Q2: What is the implementation?

Binder Connection Pooling: Android IPC mechanism (4

  • Created for each business moduleAIDLInterface and concrete implementation
  • forBinderConnection Pool CreationAIDLinterfaceIBinderPool.aidlAnd implement it
  • The remote serviceBinderPoolServiceThe realization of, inonBind()InstantiatedIBinderPoolImplementation-class object
  • BinderA concrete implementation of connection pooling to bind remote services
  • Client side call

Three. Mumble

Congratulations, has completed the wonderful IPC trip this time, if you feel the concept or a bit vague, it doesn’t matter, very normal, need not too obsessed with the details, you can continue the journey, the future of you, look at this article, there may be deeper experience, then there will be a cottage open. The future of you, will be more excellent!!

The way ahead is so long without ending, yet high and low I’ll search with my will unbending. Li SAO — Qu Yuan


If the article is a little help to you, I hope you can click on it. Your click on it is my motivation

References:

  • The difference between String and CharSequence
  • Android Interprocess Communication (IPC) : Use AIDL
  • Ipc-messenger example
  • Binder connection pools
  • Exploring the Art of Android Development
  • The point refined art | the development of the IPC

This article is formatted using MDNICE