Android IPC

一、IPC

IPC是Inter-Process Communication的缩写。
线程是CPU调度的最小单元。进程一般指一个执行单元。

多进程会导致以下几方面的问题:

1.静态成员和单例模式完全失效。

2.线程同步机制完全失效。

3.SharedPreferences的可靠性下降。

4.Application 会多次创建。

二、Serializable接口和Parcelable接口

Serializable接口:

其中Serializable接口,最好要有SerialVersionUID。

序列化的时候系统会把当前类的SerialVersionUID写入序列化的文件中,反序列的时候会去检测文件中的serialVersion是否一致。静态成员变量属于类,不属于类对象,所以不会参与序列化。同时,标示了transient的成员变量也不在序列化之列。

parcelable接口:

parcelable也是一个接口,只要实现这个接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递。

系统为我们提供了许多实现了Parcelable接口的类,他们都是可以直接序列化的,比如Intent、Bundle、Bitmap等。对于List和Map也可以实现序列化,前提是他们里面每个元素都是可序列化的。

三、Binder

Binder是Android中的一个类,它实现了IBinder接口。从IPC角度来说,Binder是Android中的一种跨进程通信方式,Binder还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder。

Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager等等)的桥梁。

从Android应用层来说,Binder是客户端和服务端进行通信的媒介。

当Bindler的工作方式:

服务端会返回一个包含了服务端业务调用的Bindler对象,通过这个Bindler对象,客服端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。

Binder主要用在Service中,包括AIDL和Messenger,其中普通Service中的Binder不涉及进程间通信。 使用AIDL来分析实现Bindler的工作机制。

它声明了一个内部类Stub,这个Stub就是一个Binder类,当客户端和服务端都位于同一个进程时,方法调用不会走跨进程的transact过程。而当两者位于不同进程时,方法调用需要走transact,这个逻辑由Stub的内部代理类Proxy来完成。AIDL核心就是它的内部类Stub和Stub的内部代理类Proxy。

四、Android中的IPC方式

Bundle:

四大组件中的三大组件(Activity、Service、Receiver)都是支持在Intent中传递Bundle数据的。因为Bundle实现了Parcelable接口。

文件共享:

文件共享也是一种进程间通信方式,两个进程通过读/写同一个文件来交换数据。

文件共享除了可以交换一些文本信息外,我们还可以序列化一个对象到文件系统中,同时从另一个进程恢复这个对象。

Android系统基于Linux,使得其并发读/写文件可以没有限制地进行。

比如SharedPreferences,SharedPreferences是Android中提供的轻量级存储方案,它通过键值对的方式来储存数据,在底层实现上它采用XML文件来存储键值对,每个应用的SharedPreferences文件都可以在当前包所在的data目录下查看到。系统对它的读/写有一定的缓存策略,即在内存中会有一份SharedPreferences文件的缓存,因此在多进程模式下,系统对它的读/写就变得不可靠。

如果需要保证数据安全,就需要加锁。

Messager:

Messger是一种轻量级的IPC方案,它的底层实现是AIDL。

Mesager的使用方法很简单。

首先在服务端创建一个Service来处理客户端的连接请求,同时创建一个Handler并通过它来创建一个Messager对象,然后在Service的onBind中返回这个Message对象底层的Bindler即可。

其次在客户端要绑定服务端的Service,绑定成功后用服务端返回的IBinder对象创建一个Messager,通过这个Messager就可以向服务端发送消息。如果需要服务端能够回应客户端,就和服务端一样,我们还需要创建一个Handler并创建一个新的Messager,并把这个messager对象通过Message的replyTo参数传给服务端,服务端通过这个replyTo参数就可以回应客户端。

AIDL:

AIDL(Android Interface Definition Language)是一种 IDL 语言,用于生成可以在 Android 设备上两个进程之间进行进程间通信(IPC)的代码。

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

其次在客户端绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转成AIDL接口所属的类型,接着就可以调用AIDL中的方法了。

最后AIDL接口的创建,在AIDL文件中,并不是所有的数据类型都是可以使用的。只有以下数据是可以的。
基本数据类型;

String和CharSequence;

List:只支持ArrayList,里面的每个元素都必须能够被AIDL支持;

Map:只支持HashMap,里面的每个元素都必须被AIDL支持,包括key和value;

Parcelable:所有实现了Parcelable接口的对象;

AIDL:所有的AIDL接口本身也可以在AIDl文件中使用。

AIDL中除了基本数据类型,其他类型的参数必须标上in、out、inout。

AIDL接口中只支持方法,不支持声明静态常量。

AIDL的包结构在服务端和客户端要保持一致,否则运行会出错,这是因为客户端需要反序列化服务端中和AIDL接口相关的所有类,如果类的完整路径不一样的话,就无法成功反序列化。

RemoteCallbackList是系统专门提供的用于删除跨进程listener的接口。RemoteCallbackList是一个泛型,支持管理任意的AIDL接口。实现方案是采用HashMap。

当客户端解注册的时候,我们只要遍历服务端所有的listener,找出那个和解注册listener具有相同Binder对象的服务端listener并把它删掉即可。RemoteCallbackList就是完成上述功能。

RemoteCallbackList使用方式:

register,unregister,同时beginBroadcast和finishBroadcast。他们俩必须配对使用。

ContentProvider:

ContentProvider是Android中提供的专门用于不同应用间进行数据共享的方式。其底层实现也是Binder。

需要注意以下细节:
1.CRUD(创建、读取、更新、删除)操作

2.防止SQL注入

其中SQL注入(SQL注入是一种常见的安全威胁,它允许攻击者通过向应用程序输入恶意构建的数据,向数据库系统发送错误的查询命令,以此来获取未授权的信息、修改数据、甚至控制整个数据库系统)

3.权限控制

Socket:

我们通过socket来实现进程间的通信。Socket也称为“套接字”,是网络通信中的概念,它分为流式套接字和用户数据报套接字两种,分别对应于网络的传输控制层中的TCP和UDP协议。

Binder连接池:


AIDL通信大致流程:

首先创建一个Service和一个AIDL接口,接着创建一个类继承自AIDL接口中的Stub类并实现Sub中的抽象方法,在Service的onBind方法中返回这个类的对象,然后客户端就可以绑定服务端Service,建立连接以后就可以访问远程服务端的方法了。

Binder连接池创建远程Service并实现IBinderPool,queryBinder的具体实现:
当Binder连接池连接上远程服务时,会根据不同模块的标识即binderCode返回不同的Binder对象,通过这个Binder对象所执行的操作全部发生在远程服务端。

选用合适的IPC方式
 

IPC方式的优缺点和适用场景
名称优点缺点适用场景
Bundle简单易用只能传输Bundle支持的数据类型四大组件间的进程间通信
文件共享简单易用不适合高并发场景,并且无法做到进程间的即时通信无并发访问情形,交换简单的数据实时性不高的场景
AIDL功能强大,支持一对多并发通信,支持实时通信使用稍复杂,需要处理好线程同步一对多通信且有RPC需求
Messenger功能一般,支持一对多串行通信,支持实时通信不能很好处理高并发情形,不支持RPC,数据通过Message进行传输,因此只能传输Bundle支持的数据类型低并发的一对多即时通信,无RPC需求,或者无须要返回结果的RPC需求
ContentProvider在数据源访问方面功能强大,支持一对多并发数据共享,可通过Call方法扩展其他操作可以理解为受约束的AIDL,主要提供数据源的CRUD操作一对多的进程间的数据共享
Socket功能强大,可以通过网络传输字节流,支持一对多并发实时通信实现细节稍微有点繁琐,不支持直接的RPC网络数据交换

其中RPC为远程过程调用 。

  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值