android aidl 使用详解

AIDL用于跨进程数据共享。


1、创建AIDL文件

AIDL(android Interface Definition Language)来定义远程接口,语法和Java接口相似,但有如下几个差异:

1)、AIDL定义接口的源代码必须以.aidl结尾

2)、AIDL接口中的用到的数据类型,除了基本类型、String、List、Map、CharSequence之外,其他类型全部都需要导包,即使他们在同一个包中也需要导包。

package com.example.entity;
import com.example.entity.Pet;
import com.example.entity.Person;


interface Ipet
{
//定义一个Person对象作为一个传入参数
	List  getPets(in Person owner);
}

定义好AIDL接口后,ADT工具会自动在gen目录下生成一个.java接口,该接口中包含一个Stub内部类,该内部类实现了IBinder、Ipet两个接口,这个Stub类将会作为远程Service的回调类,他实现了IBinder接口,因此可作为Service的onBind()方法的返回值。


2、将接口暴露给客户端


定义好AIDL接口后,接下来就可定义一个Service实现类,该service的onBind()方法返回的IBinder对象应该是ADT生成的Ipet.Stub的子类的实例。

	public class  MyBinder extends Stub {

		@Override
		public List getPets(Person owner) throws RemoteException {
			
			return pets.get(owner);
		}
		
	}

该service类开发完成之后,接下来在AndroidManifest.xml文件中配置该service,可定义action的值。



            
                
            
        


3、客户端访问AIDL Service

AIDL接口定义了两个进程之间的通信接口,因此不仅服务器需要AIDL接口,客户端同样需要前面定义的AIDL接口,因此开发客户端的第一步就是讲Service端的AIDL接口文件复制到客户端应用中,复制到客户端后ADT工具会为AIDL接口生成相应的实现。

实现步骤:

1)、创建ServiceConnection 对象

2)、以ServiceConnection对象作为参数,调用Context的bindService()方法绑定远程Service即可。


	private ServiceConnection conn = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			iService = null;
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// 返回远程service的onBind方法Ibinder对象的代理
			iService = Ipet.Stub.asInterface(service);
		}
	};

		Intent service = new Intent("com.example.SERVICE_ACTION");
		bindService(service, conn, BIND_AUTO_CREATE);

4、传递复杂数据的AIDL服务

可以传递自定义类型的。(疯狂Android:P387)


5、其他

AIDL定义时的注意事项:

(1)接口名和aidl文件名相同.

(2)接口和方法前不用加访问权限修饰符public,private,protected等,也不能用final,static.

(3)AIDL默认支持的类型包话java基本类型(int,long,boolean等)和(String,List,Map,CharSequence),使用这些类型时不需要import声明.对于List和Map中包含的元素类型必须是AIDL支持的类型.如果使用自定义类型作为参数或返回值,自定义类型必须实现Parcelable接口.

(4)自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即使在同一个包中.

(5)在aidl文件中所有非Java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入输出参数.

(6)Java原始类型默认的标记为in,不能为其它标记.

(7)oneway 关键字的使用:当接口使用oneway关键字修饰时,表示接口在远程调用时是不会block的,即接口调用时发送完transaction数据后立即返回而不会等待远端的结果。注意,这只针对IPC的调用,同样的接口如果是在同一进程内部被调用的话,oneway关键字不起任何效果,方法该阻塞就阻塞。

          

AIDL只支持接口方法,不能公开static变量。


抛出的异常是不能返回给调用者(跨进程抛异常处理是不可取的)。但是如果服务端有异常,客户端会收到RemoteException??


你可能感兴趣的:(android)