Android AIDL使用实例

本文详细介绍了Android系统中AIDL的使用方法,包括创建AIDL文件、实现接口、建立服务类和服务绑定流程等内容,帮助开发者掌握跨进程通信技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.AIDL介绍

Android系统中,进程之间不能共享内存,因此需要提供一些机制在不同进程之间进行数据通信,为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。

2.AIDL使用步骤

AIDL是不同进程间进行操作,我们需要两个项目,一个服务端,一个客户端。
服务端实现一个播放器后台Service,实现播放控制功能,比如播放、暂停、恢复、停止等。
客户端是一个Activity,显示用户界面,并通过AIDL与服务端交互,完成播放控制功能。
具体步骤如下:

2.1 服务端步骤

2.1.1 创建AIDL文件

在服务端工程中新建一个AIDL文件,IPlayer.aidl,文件内容如下:
interface IPlayer {
	int play(String url, int position);
	int pause();
	int resume();
	int seek(int position);
	int setScale(int scale);
}

在这个文件中定义接口,这个接口是对客户端提供服务的接口,可以根据需要修改。
保存后,Eclipse的ADT插件会自动把AIDL文件编译成java代码,生成在gen目录下,
文件名是IPlayer.aidl。

2.1.2 实现AIDL接口中的方法

新建 一个类,继承自动生成的IPlayer.java中的内部抽象类Stub,实现AIDL接口中方法。
例如PlayerImpl.java,文件内容如下:
public class PlayerImpl extends Stub {

	private static final String TAG = "PlayerImpl";
	@Override
	public int play(String url, int position) throws RemoteException {
		// TODO Auto-generated method stub
		Log.d(TAG, "play: url=" + url + ",position=" + position);
		return 0;
	}

	@Override
	public int pause() throws RemoteException {
		// TODO Auto-generated method stub
		Log.d(TAG, "pause!!!");
		return 0;
	}

	@Override
	public int resume() throws RemoteException {
		// TODO Auto-generated method stub
		Log.d(TAG, "resume!!!");
		return 0;
	}

	@Override
	public int seek(int position) throws RemoteException {
		// TODO Auto-generated method stub
		Log.d(TAG, "seek: position=" + position);
		return 0;
	}

	@Override
	public int setScale(int scale) throws RemoteException {
		// TODO Auto-generated method stub
		Log.d(TAG, "setScale: scale=" + scale);
		return 0;
	}

}


2.1.3 建立一个服务类

AIDL是通过Service的IBinder对象对外提供服务的,因此我们需要实现一个Service
在onBind函数中返回一个IBinder对象,自动生成的IPlayer.java中
的Stub继承自IBinder,代码如下:
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.receivebroadcast.IPlayer

而上一步中新建的PlayerImpl类又继承自Stub,因此在onBind函数中直接返回PlayerImpl即可。
新建一个PlayerService类,继承自Service,代码如下:
public class PlayerService extends Service {

	private Stub iPlayer = new PlayerImpl();
	
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		Toast.makeText(this, "ReceiveBroadcast onBind!!!", Toast.LENGTH_SHORT).show();
		return iPlayer;
	}

}

至此,服务端的工作已经全部完成。

2.2 客户端步骤

2.2.1复制AIDL文件

将服务端的AIDL文件复制到客户端,注意:AIDL文件中包名不能更改,
必须是服务端AIDL文件的包名。

2.2.2Bind Service

创建一个ServiceConnection,在onServiceConnected()中获取Server端的IBinder接口。
代码如下:
	private ServiceConnection conn = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			iPlayer = IPlayer.Stub.asInterface(service);
		}
	};

在Activity启动的时候,比如onCreate()函数中调用bindService,代码如下:
		Intent intent = new Intent();
		intent.setAction(MY_SERVICE);
		bindService(intent, conn, Service.BIND_AUTO_CREATE);

2.2.3 调用Server端AIDL中的接口

在需要与服务端通信时,调用onServiceConnected()中获取的IBinder接口中的方法,代码如下:
			if (null != iPlayer) {
				try {
					Log.d(TAG, "Send request!!!");
					iPlayer.play("http://163.com/1234.mp4", 30);
					iPlayer.pause();
					iPlayer.resume();
					iPlayer.seek(20);
					iPlayer.setScale(2);
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}

3.总结

AIDL用于进程间通信,底层采用的是Android的Binder机制,效率很高,
实测客户端发送请求的时间和服务端接收到请求的时间一致,基本没有延迟。

另外客户端的请求是同步的,服务端返回结果之后函数才返回。 

AIDL接口是自定义的,可以自定义函数名,参数等,使用比较灵活。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值