赞
踩
进程间通信简称IPC(Inter-Process Communication).Android 基于Linux,,而 Linux 出于安全考虑,不同进程间不能之间操作对方的数据,这叫做“进程隔离”。这样做的目的是为了保证每个进程的安全。
名称 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
Bundle | 简单易用 | 只能传输 Bundle 支持的数据类型 | 四大组件间的进程间通信 |
文件共享 | 简单易用 | 不适合高并发场景,并且无法做到进程间即时通信 | 无并发访问情形,交换简单的数据实时性不高的场景 |
AIDL | 功能强大,支持一对多并发通信,支持实时通信 | 使用稍复杂,需要处理好线程同步 | 一对多通信且有 RPC 需求 |
Messenger | 功能一般,支持一对多串行通信,支持实时通信 | 不能很处理高并发清醒,不支持 RPC,数据通过 Message 进行传输,因此只能传输 Bundle 支持的数据类型 | 低并发的一对多即时通信,无RPC需求,或者无需返回结果的RPC需求 |
ContentProvider | 在数据源访问方面功能强大,支持一对多并发数据共享,可通过 Call 方法扩展其他操作 | 可以理解为受约束的 AIDL,主要提供数据源的 CRUD 操作 | 一对多的进程间数据共享 |
Socket | 可以通过网络传输字节流,支持一对多并发实时通信 | 实现细节稍微有点烦琐,不支持直接的RPC | 网络数据交换 |
提到Binder,我们就会想到,他是android底层主要的进程间通信的,Binder机制只是IPC的其中一种,Android的四大组件(Activity,service,Broadcast,ContentProvider)之间的通信也是采用了Binder进行的通信。
IPC通信不得不提到两个序列化的组件,他们基本上是跟Binder绑定使用的:
Serialiazable,Parcelable
Serializable和Parcelable接口可以完成对象的序列化过程,当我们需要通过Intent和Binder传输数据的时候就需要对数据进行序列化处理。还有的时候我们需要将数据持久化保存到本地或者通过网络传输给其他终端,我们也需要Serializable完成对象的持久化。
Serialiazable:Java提供的序列化接口(标记接口)
Parcelable:android提供的序列化接口
推荐使用Parcelable
。建议使用Serializable
。下面,正式进入主题,Binder:
我们查看androidBinder底层源码发现,Binder是集成了IBinder接口,而我们从各个不同的角度来看Binder的具体使用:
1, 从IPC角度,Binder是跨进程通信方式
2, 从FrameWork角度,Binder是ServiceManager连接各种Manager(如am,wm)等的桥梁
3, 从应用层角度,Binder是客户端与服务端通信的媒介
下面来分析一下这个图,这张图,就是Binder底层框架结构图,他们是什么意思呢?
首先,Binder在Client中设置一个引用,在Server中设置一个实体,Client通过Binder间接的引用Server中的实体,这就实现了进程间的通信了。当然,Android系统不可能只为两个进程考虑通信问题,如果存在多个server,多个Client,那么此时Android系统就推出了一个Service Manager这个中间类,在这里,Service Manager就像是一个中介一样,所有的Server都必须去ServiceManager那里去注册,然后生成一个索引,此时,Client通过ServiceManager去找到这个索引,从而找到相对应的Server,这就构成了android底层多进程之间通信,而并不影响多进程的独立安全性的框架设计结构
当然,看过源码,我们知道ServiceManager他其实也是一个进程,那既然这样,Server与ServiceManager 他们之间又是如何进行通信的呢?
SMgr和其它进程同样采用Binder通信,SMgr是Server端,有自己的Binder对象(实体),其它进程都是Client,需要通过这个Binder的引用来实现Binder的注册,查询和获取。SMgr提供的Binder比较特殊,它没有名字也不需要注册,当一个进程使用BINDER_SET_CONTEXT_MGR命令将自己注册成SMgr时Binder驱动会自动为它创建Binder实体(这就是那只预先造好的鸡)。其次这个Binder的引用在所有Client中都固定为0而无须通过其它手段获得。也就是说,一个Server若要向SMgr注册自己Binder就必需通过0这个引用号和SMgr的Binder通信。类比网络通信,0号引用就好比域名服务器的地址,你必须预先手工或动态配置好。要注意这里说的Client是相对SMgr而言的,一个应用程序可能是个提供服务的Server,但对SMgr来说它仍然是个Client。
而上面说完了,我们来看Binder Driver(Binder驱动)
和路由器一样,Binder驱动虽然默默无闻,却是通信的核心。尽管名叫‘驱动’,实际上和硬件设备没有任何关系,只是实现方式和设备驱动程序是一样的。它工作于内核态,驱动负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。
Android Interface Definition Language
使用示例:
- // RemoteService.aidl
- package com.example.mystudyapplication3;
-
- interface IRemoteService {
-
- int getUserId();
-
- }
- public class RemoteService extends Service {
-
- private int mId = -1;
-
- private Binder binder = new IRemoteService.Stub() {
-
- @Override
- public int getUserId() throws RemoteException {
- return mId;
- }
- };
-
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- mId = 1256;
- return binder;
- }
- }
-
声明远程服务
- <service
- android:name=".RemoteService"
- android:process=":aidl" />
- public class MainActivity extends AppCompatActivity {
-
- public static final String TAG = "wzq";
-
- IRemoteService iRemoteService;
- private ServiceConnection mConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- iRemoteService = IRemoteService.Stub.asInterface(service);
- try {
- Log.d(TAG, String.valueOf(iRemoteService.getUserId()));
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- iRemoteService = null;
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- bindService(new Intent(MainActivity.this, RemoteService.class), mConnection, Context.BIND_AUTO_CREATE);
- }
- }
Messenger可以在不同进程中传递 Message 对象,在Message中放入我们需要传递的数据,就可以轻松地实现数据的进程间传递了。Messenger 是一种轻量级的 IPC 方案,底层实现是 AIDL。
Socket通信
此通信我们单独在后面网络进程中再讲述。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。