Android 跨进程通信--Binder

来源:互联网 发布:买家淘宝客开通条件 编辑:程序博客网 时间:2024/06/09 02:10

Binder是Android的一个类,从IPC角度来说,他是一种跨进程通信的方式;从Andtoid Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager,WindowsManager)和响应ManagerService的桥梁;从Android应用层来说,Binder是客户端和服务端进行通信的媒介,当bindService时,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个对象,客户端可以获取服务端提供的服务或者数据,这里的服务包括普通服务和AIDL服务。


以下是系统自动生成的TestAidl.java,TestAidl中只有一个int add(int num1,int num2);的方法。

/* * This file is auto-generated.  DO NOT MODIFY. * Original file: D:\\software\\adt-bundle-windows-x86-20140321\\adt-bundle-windows-x86-20140321\\eclipse\\d\\Users\\wangjy.fnst\\workspace\\AlarmTest\\src\\com\\example\\parcelable\\TestAidl.aidl */package com.example.parcelable;// 继承IInterface并且自己也是一个接口// 声明了一个内部类Stub,Stub就是Binder类,当客户端与服务端位于同一个进程,方法调用不会走Transact// 两者位于不同进程时需要走Transact过程,这个逻辑由Stub的内部代理类Proxy来实现public interface TestAidl extends android.os.IInterface {/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implementscom.example.parcelable.TestAidl {// Binder的唯一标识,一般用当前Binder的类名private static final java.lang.String DESCRIPTOR = "com.example.parcelable.TestAidl";/** Construct the stub at attach it to the interface. */public Stub() {this.attachInterface(this, DESCRIPTOR);}/** * 用于将服务端的Binder对象转换成客户端使用的AIDL接口类型的对象 * 如果位于同一进程返回Stub本身,否则返回系统封装的Stub.proxy对象 */public static com.example.parcelable.TestAidl asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof com.example.parcelable.TestAidl))) {return ((com.example.parcelable.TestAidl) iin);}return new com.example.parcelable.TestAidl.Stub.Proxy(obj);}// 返回当前Binder对象@Overridepublic android.os.IBinder asBinder() {return this;}// 处理客户端发起的跨进程请求@Overridepublic boolean onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags)throws android.os.RemoteException {// code用来标示在Transact过程中客户端所请求的是哪个方法// 从data中获取目标方法所需的参数,执行完毕向reply写入结果// 如果此方法返回false,代表客户端请求失败,可以利用这个特征来做权限验证switch (code) {case INTERFACE_TRANSACTION: {reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_add: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();int _arg1;_arg1 = data.readInt();int _result = this.add(_arg0, _arg1);reply.writeNoException();reply.writeInt(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.example.parcelable.TestAidl {private android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}@Overridepublic android.os.IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}// TestAidl中声明的int add(int num1, int num2);方法@Overridepublic int add(int num1, int num2)throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();int _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(num1);_data.writeInt(num2);mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);_reply.readException();_result = _reply.readInt();} finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public int add(int num1, int num2) throws android.os.RemoteException;}// 注意// 如果一个远程方法很耗时,不能在UI线程中发起远程请求// 由于服务端Binder方法运行在Binder线程池,所以Binder方法不管是否耗时都应采用同步方式实现,因为他已经运行在一个线程了

以下是Binder的工作机制:


0 0
原创粉丝点击