Android 跨进程通信--Binder

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 implements
			com.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对象
		@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 {
			// 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;
			}

			@Override
			public android.os.IBinder asBinder() {
				return mRemote;
			}

			public java.lang.String getInterfaceDescriptor() {
				return DESCRIPTOR;
			}

			// TestAidl中声明的int add(int num1, int num2);方法
			@Override
			public 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的工作机制:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值