如何定义AIDL进行跨进程通信

当进程A要去调用进程B中的service时,并实现通信,我们通常都是通过AIDL来操作的

工程A

首先在我们自己的包com.wzp.aidlservice中创建一个RemoteService.aidl文件,在里面我们自定义一个接口,含有方法getService()。ADT插件会在gen目录下自动生成一个RemoteService.java文件,该类中含有一个名为RemoteService.Stub的内部类,该内部类中含有AIDL文件接口的getService()方法

例如:

package com.wzp.aidlservice;
interface RemoteService { 
     String getService(); 
}


说明一:AIDL文件的位置不固定,可以任意,还有不要在定义接口中使用修饰符(private,public这些)

接着,定义自己的MyService类,在MyService类中,定义一个内部类去继承RemoteService.Stub这个内部类,实现getService方法。在onBind方法中返回这个内部类的对象,系统会自动将这个对象封装成IBinder对象,传递给它的调用者。

例如:

public class MyService extends Service { 
	public class MyServiceImpl extends RometeService.Stub { 
		@Override 
		public String getService() throws RemoteException { 
			return "AIDL例子"; 
		} 
	} 
	@Override 
	public IBinder onBind(Intent intent) { 
		return new MyServiceImpl(); 
	}
}
在onBind方法一定要返回MyServiceImpl类的对象实例,不然调用者是获取不到服务对象的

然后,需要在AndroidManifest.xml文件中配置MyService类,代码如下:

<!-- 注册服务 -->
<service android:name=".MyService">
  <intent-filter>
   <!-- 指定调用AIDL服务的ID  -->
      <action android:name="com.wzp.aidlservice.RemoteService"/>
   </intent-filter>
</service>

指定调用AIDL服务的ID是为了告诉外界(其他进程)MyService这个类能够被别的进程访问。只要别的进程知道这个ID,就能够实现通信。即本例中,进程B可以找到进程A实现通信。

注意:AIDL并不需要权限


工程B

首先我们要将工程A中生成的RemoteService.java文件拷贝到工程B中,在bindService方法中绑定AIDL。服务绑定AIDL服务就是将RemoteService的ID作为intent的action参数。

说明:如果我们单独将RemoteService.aidl文件放在一个包里,那么在我们将gen目录下的该包拷贝到工程B中。如果我们将RemoteService.aidl文件和我们的其他类存放在一起,那么我们在工程B中就要建立相应的包,以保证RmoteService.java文件的包名正确,而且我们不能修改RemoteService.java文件

bindService(new Intent("com.wzp.aidlservice.RemoteService"),serviceConnection,Context.BIND_AUTO_CREATE);

ServiceConnection的onServiceConnected(ComponentName name,IBinder service)方法中的service参数就是工程A中MyService类中继承了RemoteService.Stub类的内部类的对象。



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。