Service and Binder(2)

本文介绍了Android中AIDL(Android Interface Definition Language)用于进程间通信的原理,并详细解析了如何定义服务接口及回调接口来实现跨进程的服务调用。

Aidl生成的接口文件:

 IRemoteService.java

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: C:\\Documents and Settings\\qujianhua\\ApiTest\\src\\com\\bst\\test\\IRemoteService.aidl
 */
package com.bst.test;

/**
 * Example of defining an interface for calling on to a remote service (running
 * in another process).
 */
public interface IRemoteService extends android.os.IInterface {
	/** Local-side IPC implementation stub class. */
	public static abstract class Stub extends android.os.Binder implements
			com.bst.test.IRemoteService {
		private static final java.lang.String DESCRIPTOR = "com.bst.test.IRemoteService";

		/** Construct the stub at attach it to the interface. */
		public Stub() {
			this.attachInterface(this, DESCRIPTOR);
		}

		/**
		 * Cast an IBinder object into an com.bst.test.IRemoteService interface,
		 * generating a proxy if needed.
		 */
		public static com.bst.test.IRemoteService asInterface(
				android.os.IBinder obj) {
			if ((obj == null)) {
				return null;
			}
			android.os.IInterface iin = (android.os.IInterface) obj
					.queryLocalInterface(DESCRIPTOR);
			if (((iin != null) && (iin instanceof com.bst.test.IRemoteService))) {
				return ((com.bst.test.IRemoteService) iin);
			}
			return new com.bst.test.IRemoteService.Stub.Proxy(obj);
		}

		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 {
			switch (code) {
			case INTERFACE_TRANSACTION: {
				reply.writeString(DESCRIPTOR);
				return true;
			}
			case TRANSACTION_registerCallback: {
				data.enforceInterface(DESCRIPTOR);
				com.bst.test.IRemoteServiceCallback _arg0;
				_arg0 = com.bst.test.IRemoteServiceCallback.Stub
						.asInterface(data.readStrongBinder());
				this.registerCallback(_arg0);
				reply.writeNoException();
				return true;
			}
			case TRANSACTION_unregisterCallback: {
				data.enforceInterface(DESCRIPTOR);
				com.bst.test.IRemoteServiceCallback _arg0;
				_arg0 = com.bst.test.IRemoteServiceCallback.Stub
						.asInterface(data.readStrongBinder());
				this.unregisterCallback(_arg0);
				reply.writeNoException();
				return true;
			}
			case TRANSACTION_updateValue: {
				data.enforceInterface(DESCRIPTOR);
				this.updateValue();
				reply.writeNoException();
				return true;
			}
			}
			return super.onTransact(code, data, reply, flags);
		}

		private static class Proxy implements com.bst.test.IRemoteService {
			private android.os.IBinder mRemote;

			Proxy(android.os.IBinder remote) {
				mRemote = remote;
			}

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

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

			/**
			 * Often you want to allow a service to call back to its clients.
			 * This shows how to do so, by registering a callback interface with
			 * the service.
			 */
			public void registerCallback(com.bst.test.IRemoteServiceCallback cb)
					throws android.os.RemoteException {
				android.os.Parcel _data = android.os.Parcel.obtain();
				android.os.Parcel _reply = android.os.Parcel.obtain();
				try {
					_data.writeInterfaceToken(DESCRIPTOR);
					_data.writeStrongBinder((((cb != null)) ? (cb.asBinder())
							: (null)));
					mRemote.transact(Stub.TRANSACTION_registerCallback, _data,
							_reply, 0);
					_reply.readException();
				} finally {
					_reply.recycle();
					_data.recycle();
				}
			}

			/**
			 * Remove a previously registered callback interface.
			 */
			public void unregisterCallback(
					com.bst.test.IRemoteServiceCallback cb)
					throws android.os.RemoteException {
				android.os.Parcel _data = android.os.Parcel.obtain();
				android.os.Parcel _reply = android.os.Parcel.obtain();
				try {
					_data.writeInterfaceToken(DESCRIPTOR);
					_data.writeStrongBinder((((cb != null)) ? (cb.asBinder())
							: (null)));
					mRemote.transact(Stub.TRANSACTION_unregisterCallback,
							_data, _reply, 0);
					_reply.readException();
				} finally {
					_reply.recycle();
					_data.recycle();
				}
			}

			public void updateValue() 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_updateValue, _data,
							_reply, 0);
					_reply.readException();
				} finally {
					_reply.recycle();
					_data.recycle();
				}
			}
		}

		static final int TRANSACTION_registerCallback = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
		static final int TRANSACTION_unregisterCallback = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
		static final int TRANSACTION_updateValue = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
	}

	/**
	 * Often you want to allow a service to call back to its clients. This shows
	 * how to do so, by registering a callback interface with the service.
	 */
	public void registerCallback(com.bst.test.IRemoteServiceCallback cb)
			throws android.os.RemoteException;

	/**
	 * Remove a previously registered callback interface.
	 */
	public void unregisterCallback(com.bst.test.IRemoteServiceCallback cb)
			throws android.os.RemoteException;

	public void updateValue() throws android.os.RemoteException;
}


IRemoteServiceCallback.java

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: C:\\Documents and Settings\\qujianhua\\ApiTest\\src\\com\\bst\\test\\IRemoteServiceCallback.aidl
 */
package com.bst.test;

/**
 * Example of a callback interface used by IRemoteService to send synchronous
 * notifications back to its clients. Note that this is a one-way interface so
 * the server does not block waiting for the client.
 */
public interface IRemoteServiceCallback extends android.os.IInterface {
	/** Local-side IPC implementation stub class. */
	public static abstract class Stub extends android.os.Binder implements
			com.bst.test.IRemoteServiceCallback {
		private static final java.lang.String DESCRIPTOR = "com.bst.test.IRemoteServiceCallback";

		/** Construct the stub at attach it to the interface. */
		public Stub() {
			this.attachInterface(this, DESCRIPTOR);
		}

		/**
		 * Cast an IBinder object into an com.bst.test.IRemoteServiceCallback
		 * interface, generating a proxy if needed.
		 */
		public static com.bst.test.IRemoteServiceCallback asInterface(
				android.os.IBinder obj) {
			if ((obj == null)) {
				return null;
			}
			android.os.IInterface iin = (android.os.IInterface) obj
					.queryLocalInterface(DESCRIPTOR);
			if (((iin != null) && (iin instanceof com.bst.test.IRemoteServiceCallback))) {
				return ((com.bst.test.IRemoteServiceCallback) iin);
			}
			return new com.bst.test.IRemoteServiceCallback.Stub.Proxy(obj);
		}

		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 {
			switch (code) {
			case INTERFACE_TRANSACTION: {
				reply.writeString(DESCRIPTOR);
				return true;
			}
			case TRANSACTION_valueChanged: {
				data.enforceInterface(DESCRIPTOR);
				int _arg0;
				_arg0 = data.readInt();
				this.valueChanged(_arg0);
				return true;
			}
			}
			return super.onTransact(code, data, reply, flags);
		}

		private static class Proxy implements
				com.bst.test.IRemoteServiceCallback {
			private android.os.IBinder mRemote;

			Proxy(android.os.IBinder remote) {
				mRemote = remote;
			}

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

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

			/**
			 * Called when the service has a new value for you.
			 */
			public void valueChanged(int value)
					throws android.os.RemoteException {
				android.os.Parcel _data = android.os.Parcel.obtain();
				try {
					_data.writeInterfaceToken(DESCRIPTOR);
					_data.writeInt(value);
					mRemote.transact(Stub.TRANSACTION_valueChanged, _data,
							null, android.os.IBinder.FLAG_ONEWAY);
				} finally {
					_data.recycle();
				}
			}
		}

		static final int TRANSACTION_valueChanged = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
	}

	/**
	 * Called when the service has a new value for you.
	 */
	public void valueChanged(int value) throws android.os.RemoteException;
}


 

### 服务启动检查、线程池线程数及Binder线程可用性分析 为了验证服务是否成功启动,可以采用多种方法来确认其状态。通常情况下,可以通过特定的日志记录机制或者通过调用某些API接口来进行健康检查[^1]。 #### 检查服务是否启动 服务的状态可以通过监听器或管理端点实现监控功能。如果服务实现了Spring Boot Actuator,则可以直接访问`/actuator/health`路径以获取当前的服务运行状况。如果没有此类工具支持,也可以自定义一个简单的HTTP请求处理程序,在其中返回服务的核心组件初始化完成标志作为响应数据[^2]。 #### 获取线程池中的线程数量 对于Java应用程序而言,尤其是那些基于Executor框架构建的应用场景下,要统计线程池内的活动线程数目非常简单。只需创建一个继承ThreadPoolExecutor类的对象实例,并利用getPoolSize()方法即可得到正在执行任务的工作线程总数;而getActiveCount()则用于报告此刻正忙于工作的实际线程计数值[^3]。 ```java int poolSize = ((ThreadPoolExecutor) executorService).getPoolSize(); int activeThreads = ((ThreadPoolExecutor) executorService).getActiveCount(); System.out.println("Current Pool Size: " + poolSize); System.out.println("Currently Active Threads: " + activeThreads); ``` #### Binder线程的启动与可用情况检测 Android系统内部维护了一组专门负责跨进程通信(IPC)操作的特殊工作线程——即所谓的Binder线程。这些线程由Binder驱动自动管理和调度,开发者一般无需手动干预它们的行为模式。然而当涉及到复杂应用架构设计时可能仍需关注此方面信息。一种间接判断方式就是尝试发起一次典型的AIDL交互过程看是否会抛出异常从而推测目标进程中是否存在有效的Binder实体对象处于就绪待命状态之中[^4]。 ```java try { IRemoteService remoteService = RemoteServiceManager.getRemoteService(); String response = remoteService.getData(); // 假设这是一个标准远程方法调用 System.out.println("Binder Thread Available and Service Responded With:" + response); } catch (DeadObjectException e){ System.err.println("The service's process has died or crashed."); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值