Android进程间通讯——AIDL

AIDL (Android Interface Definition Language) ,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。在使用AIDL前,必须要绑定service——bindService。

使用AIDL的步骤:
1.创建一个包名用来存放aidl文件,如果需要传递自定义对象,还需要建立对象的aidl文件,这里我们由于使用了自定义对象Student,所以,还需要创建Student.aidl和Student.java(两者必须同名)。注意,这三个文件,需要都放在同一个包里。

说明:

aidl中支持的参数类型为:基本类型(int,long,char,boolean等),String,CharSequence,List,Map,其他类型必须使用import导入

接口中的参数除了aidl支持的类型,其他类型必须标识其方向:到底是输入还是输出抑或两者兼之,用in,out或者inout来表示,

2.Student.aidl代码如下:

package com.fy.market.aidl;

parcelable Student;
说明:这里parcelable是个类型,首字母是小写的,和Parcelable接口不是一个东西,接口和方法声明都不用public,方法加入public会提示错误

通过AIDL传输非基本类型的对象,被传输的对象需要序列化

在gen下面可以看到,eclipse为我们自动生成了一个代理类
public static abstract class Stub extends android.os.Binder implements com.ryg.sayhi.aidl.IMyService
可见这个Stub类就是一个普通的Binder,只不过它实现了我们定义的aidl接口。它还有一个静态方法
public static com.ryg.sayhi.aidl.IMyService asInterface(android.os.IBinder obj)
这个方法很有用,通过它,我们就可以在客户端中得到IMyService的实例,进而通过实例来调用其方法
3.服务端(service)
实现
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
displayNotificationMessage("服务已启动");  
return mBinder;  
}

 和
private final IMyService.Stub mBinder =new IMyService.Stub() {

@Override
public List<Student> getStudent() throws RemoteException {
// TODO Auto-generated method stub
synchronized (mStudents) {
return mStudents;
} 
}

@Override
public void addStudent(Student student) throws RemoteException {
// TODO Auto-generated method stub
synchronized (mStudents) {
if (!mStudents.contains(student)) {
mStudents.add(student);
}
}
}
/**
* 在这里可以做权限认证,return false意味着客户端的调用就会失败,比如下面,只允许包名为com.example.test的客户端通过, 
* 其他apk将无法完成调用过程  
*/

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
// TODO Auto-generated method stub
String packageName = null;
String[] packages = AIDLService.this.getPackageManager()
.getPackagesForUid(getCallingUid());
if (packages != null && packages.length > 0) {
packageName = packages[0];
}
if (!PACKAGE_SAYHI.equals(packageName)) {
return false;
}
return super.onTransact(code, data, reply, flags);  
}

};
4.客户端(clident)
实现接口ServiceConnection,并拿到服务端返回的I Binder
@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			 //通过服务端onBind方法返回的binder对象得到IMyService的实例,得到实例就可以调用它的方法了  
            mIMyService = IMyService.Stub.asInterface(service);  
            try {
            	if (mIMyService.getStudent().size()>0) {
            		Student student = mIMyService.getStudent().get(mIMyService.getStudent().size()-1);
            		showDialog(student.toString());  
					
				}
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}  
		}
理解:
进程Activity通过bindService(intent, ServiceConnection, BIND_AUTO_CREATE);启动Service,也就是开启进程Service,并且将 ServiceConnection传递到Service中,关于ServiceConnection的作用:
/**
 * Interface for monitoring the state of an application service.  See
 * {@link android.app.Service} and
 * {@link Context#bindService Context.bindService()} for more information.
 * <p>Like many callbacks from the system, the methods on this class are called
 * from the main thread of your process.

 */
我的理解是类似于Callback,但仅仅是类似,并不是真正的callback,两个进程间没法实现callback,这也间接的说明了onBind返回的和onServiceConnected 中的Service不是一个IBind。启动到Service,然后Service中实现private final IMyService.Stub mBinder =new IMyService.Stub() ;并通过onBind返回给Activity,Activity实现接口ServiceConnection的onServiceConnected方法拿到实现了的自定义的aidl接口(拿到的和Service中的不是同一个)。
参考资料:
http://blog.csdn.net/singwhatiwanna/article/details/17041691#reply
demo:(
里面只有activity.java和service.java两个文件,因为很多的实验都写在了一个工程中,所以只能拿出这两个文件,你需要自建工程,并在清单文件中声明(service 必须有android:process=":remote",要不和activity在同一进程中) ):点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值