内容简介:进程隔离是为保护操作系统中进程互不干扰而设计的一组不同硬件和软件的技术。进程数据不共享,进程A的虚拟地址和进程B的虚拟地址不同,这样就防止进程A将数据信息写入进程B,保证了数据的安全性。Linux 下的传统 IPC 通信原理:传输过程:
进程隔离是为保护操作系统中进程互不干扰而设计的一组不同硬件和软件的技术。进程数据不共享,进程A的虚拟地址和进程B的虚拟地址不同,这样就防止进程A将数据信息写入进程B,保证了数据的安全性。
- 进程空间分为内核空间和用户空间,内核空间(Kernel)是系统内核运行的空间。用户空间(User Space)是用户程序运行的空间,他们之间是隔离的。
- 内核有访问的所有权限,用户空间也可以通过系统接口去访问内核空间。用户空间可以通过内核空间(类似于中介者)进行相互访问。
2、 Linux 进程间IPC方式:
- 管道
- 消息队列
- 共享内存
- 套接字
- 信号量
- 信号
Linux 下的传统 IPC 通信原理:
传输过程:
内存缓存区 --> 内核缓存区 --> 内存缓存区,需要 2 次数据拷贝;
3、Binder机制的特点
(1)传输性能
- Binder数据拷贝只需要一次,而消息队列、管道、Socket等需要两次,共享内存一次拷贝都不需要。Binder性能仅次于共享内存。
(2)稳定性
- Binder基于C/S架构,Server端和Client端相对独立,稳定性好。
- 共享内存没有Server端和Client端的区分,可能存在同步死锁等问题。Binder稳定性优于共享内存。
(3)安全性
- 传统的Linux通信方式无法获取对方进程的UID,所以访问接入点是开放的,不安全。
- Android为每个应用程序分配了自己的UID,作为自身的标识。Binder的方式可以通过UID建立私有通道,Binder的安全性更高。
二、Binder机制实现原理
1、内存映射
Binder IPC正是基于内存映射(mmap)来实现的
Binder通信过程:
- 首先 Binder 驱动在内核空间创建一个数据接收缓存区;
- 接着在内核空间开辟一块内核缓存区, 建立内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系;
- 发送方进程通过系统调用 copy_from_user() 将数据 copy 到内核中的内核缓存区 ,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就 相当于把数据发送到了接收进程的用户空间 ,这样便完成了一次进程间的通信。
2、Binder通信模型
- 包括 Client、Server、ServiceManager、Binder 驱动。
- 其中 Client、Server、Service Manager 运行在用户空间,Binder 驱动运行在内核空间。
- 对于Client,Binder是Server本地对象的一个引用,这个引用实际上是一个代理对象,Client通过这个代理对象来间接访问Server的本地对象。
- 对于Server,Binder是提供具体实现的本地对象,需向ServiceManager注册。
- Binder驱动是连接Client来Server的桥梁,负责将代理对象转化为本地对象,并将Server的执行结果返回给Client。
- ServiceManager它保存了Server Binder字符名称和Binder引用的映射,Client通过它来找到Server的Binder引用。
3、Binder通信过程:
- 一个进程使用 BINDERSETCONTEXT_MGR 命令通过 Binder 驱动将自己注册成为 ServiceManager;
- Server 通过驱动向 ServiceManager 中注册 Binder ,表明可以对外提供服务。驱动为这个 Binder 创建位于内核中的实体节点以及 ServiceManager 对实体的引用,将名字以及新建的引用打包传给 ServiceManager,ServiceManger 将其填入查找表。
- Client 通过名字,在 Binder 驱动的帮助下从 ServiceManager 中获取到对 Binder 实体的引用 ,通过这个引用就能实现和 Server 进程的通信。
三、AIDL
1、AIDL使用的基本步骤
(1)生成AIDL接口(new->AIDL->AIDL File)
interface MyWindowManager { void sysout(); } 复制代码
生成AIDL文件之后,比起以前多了一个叫做 aidl 的包,而且他的层级是和 java 包相同的。
(2)编译MyWindowManager.aidl生成Java文件
public interface MyWindowManager extends android.os.IInterface { /** Local-side IPC implementation stub class. */ //Stub 继承 Binder, 说明它是一个 Binder 本地对象;实现 IInterface 接口,表明Server可以提供的方法 public static abstract class Stub extends android.os.Binder implements com.example.myview.binder.MyWindowManager { private static final java.lang.String DESCRIPTOR = "com.example.myview.binder.MyWindowManager"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } public static com.example.myview.binder.MyWindowManager asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.example.myview.binder.MyWindowManager))) { return ((com.example.myview.binder.MyWindowManager) iin); } return new com.example.myview.binder.MyWindowManager.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { ...... return super.onTransact(code, data, reply, flags); } //Binder本地代理对象 private static class Proxy implements com.example.myview.binder.MyWindowManager { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public void sysout() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_sysout, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_sysout = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } public void sysout() throws android.os.RemoteException; } 复制代码
- MyWindowManager继承了IInterface,是Client和Server通信的接口
- Stub为静态抽象内部类,继承了Binder。其子类需要实现MyWindowManager接口, 是Server的Binder的本地对象
- Stub.Proxy为静态内部类,内部包含了IBinder对象, 是Server在Client中的本地代理对象 ,将参数序列化后交给mRemote处理,实现了跟远程Stub的通信
- asInterface方法通常是Client在bindService成功后,由Client来调用的,作用是将绑定成功后返回的IBinder对象转换为具体的IInterface接口。Client拿到这个IInterface接口后跟Server进行通信
(3)Server端提供方法的具体实现
public class MyWindowManagerService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return mWindowManager; } private final MyWindowManager.Stub mWindowManager = new MyWindowManager.Stub() { @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } @Override public void sysout() throws RemoteException { Log.e("hj", "sysout: " ); } }; } 复制代码
(4)其他进程的Activity实现跟Service的通信
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, MyWindowManagerService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { MyWindowManager windowManager = MyWindowManager.Stub.asInterface(service); try { windowManager.sysout(); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; } 复制代码
2、IBinder/IInterface/Binder/BinderProxy/Stub
- IBinder : IBinder 是一个接口,代表了一种跨进程通信的能力。只要实现了这个借口,这个对象就能跨进程传输。
- IInterface : IInterface 代表的就是 Server 进程对象提供了哪些方法
- Binder : Java 层的 Binder 类,代表的其实就是 Binder 本地对象。 Proxy 类是 Binder 类的一个内部类,它代表远程进程的 Binder 对象的本地代理 ;这两个类都继承自 IBinder, 因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder 驱动会自动完成这两个对象的转换。
- Stub : AIDL 的时候,编译 工具 会给我们生成一个名为 Stub 的静态内部类;这个类继承了 Binder, 说明它是一个 Binder 本地对象,它实现了 IInterface 接口,表明它具有 Server 承诺给 Client 的能力;Stub 是一个抽象类,具体的 IInterface 的相关实现需要自己实现。
以上所述就是小编给大家介绍的《Android进阶(六)Binder机制》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 快速失败机制 & 失败安全机制
- JavaScript线程机制与事件机制
- 区块链是怎样将分布式组网机制、合约机制、共识机制等技术结合并应用
- Java内存机制和GC回收机制-----笔记
- javascript垃圾回收机制 - 标记清除法/引用计数/V8机制
- Android 8.1 源码_机制篇 -- 全面解析 Handler 机制(原理篇)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
京东平台运营攻略(全彩)
京东商学院 / 电子工业出版社 / 2015-5 / 69.00元
2014 年年末,京东POP 开放平台的入驻商家已超过6 万,京东平台被广泛关注和认可的同时,在电商江湖中仍颇具神秘色彩。面对碎片化的信息,京东的店铺经营者及希望入驻京东的准商家们,对于在京东如何利用丰富的各类平台资源,搭建并运营京东店铺,一直很难找到全面而系统的资料。 《京东平台运营攻略(全彩)》由京东官方出品,动员了京东内部涉及第三方店铺业务线的众多部门,由多位业务精英参与撰写,保证了内......一起来看看 《京东平台运营攻略(全彩)》 这本书的介绍吧!