Android multi-process communication, Binder, IPC mechanism this one is enough! ! !

Android IPC Profile

IPC meaning: inter-process communication, refers to exchange data between two processes enjoy.
Multi-process usage scenarios:

  • Be implemented according to business needs require multiple processes
  • In order to increase the memory an application that can be used so it is necessary to obtain multiple copies of multi-process memory space.

Android multi-process mode

It refers to a multiple application processes in general. Use multiple processes there is only one way in Android, android is specified in the manifest file to the four components (Activity, Service, Receiver, ContentProvider): process attributes, in addition no other way. In fact, there is a special, is through JNI had to fork a new process in native.

Example:
Here Insert Picture Description
enter name ":" the process at the beginning of the current application process is privately owned, and its other application components can not be run in the same process. Not to ":" at the beginning of a global process, other applications and it can be soaked in the same process by ShareUID way.

Android will be a unique ShareUID assigned to each application, with application to share data in the same UID. By ShareUID two applications running in the same process, there is a requirement, you need two applications have the same ShareUID and signature can. So that they can access the private data of each other.


Multi-process mode of operation mechanism

We have created a class in SecondActivity, and then there is a public static member variables in this class.
Here Insert Picture Description

Then we modify MainActivity in sUserID is 2, then we look at the print log:
Here Insert Picture Description

The above-mentioned problems Analysis: We know that each application is assigned a separate virtual machine, or is assigned a separate virtual machine for each process as Android, different virtual machines on memory allocation and a different address space, has led to access a class object in different virtual machines will produce multiple copies. So after we changed the value of the process SecondActivity, and the process MainActivity value does not change. This is the core reason.

So we summarize multi-process summarize the problem:

  • 1, all running in different processes of the four components will be shared as long as the shared data through the memory failure
  • 2, static and total failure singleton
  • 3, thread synchronization mechanism completely ineffective
  • 4, SP decreased reliability
  • 5, Application will create many times

1,2,3 problem: both because it is not a memory, so there will be problems, as for thread synchronization, too, locked the object is not subject to the same memory address so there will be problems.
The first four questions: SP does not support the two processes at the same time to read and write, or else a chance to lose data because SP Town is achieved by reading and writing XML, concurrent write clearly possible to realize the problem.
The first five questions: When a form to run in a new process, the system will also allocate a separate virtual machine, this process is actually start an application, start the application certainly restart Application, so there will be multiple Application.

This section describes the problems associated with multi-process, then we have to understand IPC much easier.


Sequence of two ways

The reason why is because of the sequence presented here: the object is not transmitted across processes, across the process object of transmission are essentially deserialization process

Serializable Interface

1, which is provided by a serialized Java interfaces, it is an empty interface, only need to implement this interface to the object. very simple.
2, using ObjectOutputStream and ObjectInputStream can be easily achieved.
Here Insert Picture Description

The above demonstrates the typical process using Serializable way to serialize objects, is very simple, just need to implement the Serializable interface User objects written to a file on it restored, but the content and user objects newUser recovery after the note exactly the same, but the two are not the same object.

3, and then we explain serialVersionUID,
Here Insert Picture Description
serialization, when the current system will serialVersionUID write serialized file (may also be an intermediary), when the anti-sequence system detects files serialVersionUID go back, and see if it is currently the same version of the class, this time can be successfully deserialized; otherwise explain the current class and sequence of occurrence compared to some changes, such as the number of member variables happened, can not be deserialized success.

Parcelable Interface

This sequence is provided android interfaces, a class object is achieved by a series of intent binder can be passed.
Here Insert Picture Description
Here Insert Picture Description

Contrast: Serializable simple but significant overhead, Parcelable is Android in serialization, but recommended.


Binder working mechanism

Here Insert Picture Description


Android in the way IPC

  • Bundle ships with Intent
  • Using File Sharing
  • Use Messenger
  • Use AIDL
  • Use ContentProvider
  • Use Socket

1, Bundle

Three of the four components of the component (Activity, Service, Receiver) supports data transfer Bundle in the Intent. Since Bundle implements Parcelable interface, so it can be transferred between different processes. Based on this we started a process in the Activity, Service and Receiver another process, we will be able to deliver in the past Bundle by Intent, the simplest


2, the use of file sharing

It should be noted about the SP, it is rather special, it is the underlying to store key-value pairs through an XML file. It is also a kind of file, but because the system has some of its read and write caching strategy, that there will be a memory sub-SO file caching, because the next multi-process mode, the system read and write it becomes unreliable.

我们从MainActivity中序列化User对象到SD卡上,然后在SecondActivity的onResume中去反序列化,我们期望在SecondAcvity中能够正确获取User对象的值。
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
我们打印日志看一下,但是注意一下,只能说是内容相同,已经不是同一个对象了,是两个对象。
Here Insert Picture Description


3、使用Messenger

它是轻量级的IPC方案,它的底层实现是AIDL。先看一下构造方法:
Here Insert Picture Description

使用方法如下:
1)服务端进程
首先,我们需要在服务端创建一个Servicer来处理客户端的连接请求,同时创建一个Handler并通过它来创建一个Messenger对象,然后在Service的onBind中返回这个Messenger对象底层的binder即可。

2)客户端进程
客户端进程中,首先要绑定服务端的Service,绑定成功后用服务端返回的IBinder对象创建一个Messenger,通过这个Messenger就可以向服务端发消息了,发消息类型为Message对象。如果需要服务端能够回应客户端,就和服务端一样,我们还需要创建一个Handler并创建一个Messenger,并把这个Messenger对象通过Message的replyTo参数传递给服务端,服务端通过这个replyTo参数就可以回应客户端。

首先看服务端代码:

Here Insert Picture Description
Here Insert Picture Description
看一下客户端代码:
Here Insert Picture Description
Here Insert Picture Description
然后看一下运行结果:
Here Insert Picture Description
上面是一个简单的例子,如果我们在修改一下,就是每当客户端发来一条消息,服务端就自动回复一条“嗯,你的消息我已经收到,稍后回复你”,代码修改如下:
首先看服务端修改,只修改MessengerHandler:

Here Insert Picture Description
Here Insert Picture Description
接下来客户端修改:
客户端也需要准备一个接收消息的Messenger和Handler:
Here Insert Picture Description
很关键的一点,需要把接收服务端消息的Messenger通过Message的replyTo传递给服务端:

Here Insert Picture Description
打印如下:
Here Insert Picture Description
Here Insert Picture Description


4、使用AIDL

通过上面对Messenger介绍之后,发现它是串行的,如果信息量太大,会排队,所以适合轻量级交互。
我介绍一下AIDL的使用

1、服务端
服务端首先要创建一个Service用来监听客户端的连接请求,然后创建一个AIDL文件,将将暴露给客户端的接口声明在AIDL文件中,最后在Service中实现这个接口即可。

2、客户端
客户端所要做事情就稍微简单一些,首先绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转换成AIDL接口所属的类型,接着就可以调用AIDL中的方法了。

3、AIDL接口的创建
Here Insert Picture Description

AIDL支持的数据类型:
Here Insert Picture Description

远程服务端Service的实现:
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

客户端实现
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
紧着着我们在调用李刚一个接口addBook,修改onServiceConnected
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
通过上面例子大家应该对AIDL有了初步的了解,下面我们在优化一下方案需求,每个用户可以对服务端设置提醒和取消提醒功能,服务端有了新书以后会主动通知设置提醒的用户。并把新书当作参数传递给用户:

Here Insert Picture Description
Here Insert Picture Description
还需要在AIDL接口中,添加两个方法,注册和解除注册
Here Insert Picture Description

然后服务端代码也要改一下,然后还有添加一个线程,5s加一本书,通知用户
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

看一下客户端修改代码:

Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

看日志打印:确实没5s更新一次:
Here Insert Picture Description
ok,我们在onDestroy的时候已经解除绑定,我们在返回的时候会有一个错误:
Here Insert Picture Description
但是我们代码已经明明传过去listener过去了,最终服务端没有解注册成功。为什么呢? 这就是我们之前给大家提到的,跨进程通信是序列化和反序列的的形式,只不过是内容相同而已。但是还是两个不同的对象,所以解注册失败。那怎么解决呢?答案是使用RemoteCallbackList,它是专门提供用于删除跨进程接口的。它实现原理很简单,在它的内部有一个Mao结构专门用来保存所有的AIDL的回调,这么Map的key是IBinder类型,value是Callback类型。
Here Insert Picture Description
看上面应该明白了,他们生成的是同一个IBinder对象,利用这一点,我们遍历服务端的listener,找出哪个和解注册listener具有相同的Binder对象服务端删除即可。

BookManagerSercice修改:把CopyOnWriteArrayList替换成RemoteCallbackList
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
欧克,修改完毕,我们打印日志看一下效果

Here Insert Picture Description
使用注意,我们无法像操作List一样去操作它,尽管它的名字也带个List,但是它并不是一个LIst。遍历RemoteCallbackList必须按照下面的方式进行,其中beginBroadcast和finishBroadcast必须要配对使用。
Here Insert Picture Description

5、使用ContentProvider

6、使用Socket

由于时间问题,5 和6 我就不粘贴案例了,以后时间充足我在补上。


Binder连接池

最后给大家介绍一下Binder连接池, 它是解决业务模块如果需要多个AIDL的时候,不需要创建多个服务,通过连接池可以取出不同Binder,不同的Binder我们自己定义Code来区分,获取即可。
Here Insert Picture Description

We offer two AIDL interfaces (ISecurityCenter and ICompute)
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
implement two interfaces:
Here Insert Picture Description
Create a connection pool Binder AIDL interfaces
Here Insert Picture Description
Here Insert Picture Description
to create and implement a remote Service IBinderPool, wire surface is achieved:
Here Insert Picture Description
Remote Service:
Here Insert Picture Description
Here Insert Picture Description
The following is a concrete realization of Binder connection pool, in first, it within them to go to a remote service binding, the query returns a different Binder after success. The object is achieved AIDL
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

Activity code is as follows:
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

Here Insert Picture Description

Published 51 original articles · won praise 78 · views 30000 +

Guess you like

Origin blog.csdn.net/weixin_39079048/article/details/89178521