目标
- 了解Binder和AIDL在Android中的定位
- 学会使用AIDL
AIDL和Binder的介绍
Binder是什么
Binder的前身是OpenBinder,它是一种通过提供远程过程调用(RPC)功能进程间通信的机制,是Android系统中的重要组成部分。
在Android系统的Binder机制中,由一系统组件组成,分别是:Client、Server、ServiceManager和binder驱动。其中Client、Server和ServiceManager运行在用户空间,binder驱动运行在内核空间,binder驱动程序是核心组件,ServiceManager提供管理功能,Client和Server在binder驱动和ServiceManager提供的基础设施上进行Client-Server之间的通信。
在应用中,当bindService发生时,Server会返回一个包含了Server端业务调用的Binder对象,通过这个Binder对象,Client端就可以获取Server端提供的服务或者数据,这里的服务包含普通服务和基于AIDL的服务。
AIDL是什么
AIDL全称是:Android Interface Definition Language,即Android接口定义语言。
Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。Android中采用接口定义语言(Interface Definition Language,IDL)来公开服务的接口,以便Android中跨进程访问的实现,这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。
注:四个Android应用程序组件(Service、Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问。
AIDL实现进行进程间通信
Server端
创建一个Server端,在aidl资源包中创建 package和.aidl文件
- 创建aidl的资源包:右键点击项目->New->Aidl
-
创建package(包名:com.teresa.aidlservice)
-
创建.aidl文件
package com.teresa.aidlservice;
interface IMyAidlInterface {
//send data by this interface
String getString();
}
编译.aidl文件,生成它对应的java文件
选择菜单build,即可进行编译生成.java文件在项目的build目录下:
系统自动生成IMyAidlInterface.java文件,我们直接使用即可,生成的java文件内容如下:
public interface IMyAidlInterface extends android.os.IInterface
{
//1.IMyAidlInterface接口的方法,我定义的。
public java.lang.String getString() throws android.os.RemoteException;
//2.IMyAidlInterface的默认实现类
public static class Default implements com.teresa.aidlservice.IMyAidlInterface
{
@Override
public java.lang.String getString() throws android.os.RemoteException
{
return null;
}
@Override
public android.os.IBinder asBinder() {
return null;
}
}
//3.IMyAidlInterface接口中的内部抽象类Sub,实现IMyAidlInterface接口同时继承Binder类,是Binder的实体类
public static abstract class Stub extends android.os.Binder implements com.teresa.aidlservice.IMyAidlInterface
{
//3.1 IMyAidlInterface的描述符
private static final java.lang.String DESCRIPTOR = "com.teresa.aidlservice.IMyAidlInterface";
//3.2 表示我们定义的getString方法的操作指令,用于判断运行的是getString方法
static final int TRANSACTION_getString = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
//3.3 Stub()构造方法把this和DESCRIPTOR进行关联,如果Client和Server在同一个进程,queryLocalInterface(descriptor)就会返回此Stub的对象
public Stub(){
this.attachInterface(this, DESCRIPTOR);}
//3.4 asInterface方法:把IBinder对象转换成IMyAidlInterface的实现对象。Client和Server在同一个进程,obj=Sub对象,Client和Server不在同一个进程,obj=BinderProxy对象
public static com.teresa.aidlservice.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
//BinderProxy类中:public IInterface queryLocalInterface(String descriptor) {return null;},返回null
//3.4.1 如果iin!=null,那么表示Client和Server在同一个进程,此时返回Sub(Binder)对象
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.teresa.aidlservice.IMyAidlInterface))) {
return ((com.teresa.aidlservice.IMyAidlInterface)iin);
}
//3.4.2 如果iin==null,那么表示Client和Server不在同一个进程,此时返回Sub.Proxy对象。Proxy对象内部包含Sub的代理类对象obj,它是一个BinderProxy对象。
return new com.teresa.aidlservice.IMyAidlInterface.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder(){
return this;}
//3.5 onTransact方法:处理mRemote.transact()过来的内容,然后把结果写入mRemote传过来的reply中并返回去。
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
java.lang.String descriptor = DESCRIPTOR;
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(descriptor);
return true;
}
case TRANSACTION_getString:
//3.5.1 调用this.getString()返回_result,并把_result 写入reply中。
{
data.enforceInterface(descriptor);
java.lang.String _result = this.getString();
reply.writeNoException();
reply.writeString(_result);
return true;//3.5.2 返回true表示处理成功,reply也会携带_result回到Proxy类中的getString()方法中。
}
default:
{
return super.