AIDL:Android Interface Definition Language
利用AIDL,客户端和服务器之间可以顺利的进行进程间通讯(IPC)
按照上一章内容android bindService(),如果不需要使用并发的IPC,您应该通过继承Binder来创建您的通讯接口,或者,如果确实需要使用IPC,但是不需要处理多线程,那继承Messenger来实现通讯接口。
只有允许来自不同应用的客户端访问您的IPC Service并且您希望在Service中处理多线程,使用AIDL才是必要的。
AIDL的用法:
Service端:
1.创建一个.aidl文件
使用java程序语言的语法声明AIDL interface,然后Android SDK工具会基于这个.aidl文件自动生成一个IBinder的接口并且把它保存到工程的gen文件夹下。
1 // IRemoteService.aidl 2 package com.example.android; // Declare any non-default types here with import statements /** Example service interface */ 3 interface IRemoteService { 4 5 /** Request the process ID of this service, to do evil things with it. */ 6 int getPid(); 7 8 /** Demonstrates some basic types that you can use as parameters 9 * and return values in AIDL. 10 */ 11 void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, 12 double aDouble, String aString); 13 }
2.实现.aidl中的interface
1 private final IRemoteService.Stub mBinder = new IRemoteService.Stub() { 2 public int getPid(){ 3 return Process.myPid(); 4 } 5 public void basicTypes(int anInt, long aLong, boolean aBoolean, 6 float aFloat, double aDouble, String aString) { 7 // Does nothing 8 } 9 };
3.为客户端公开接口
一旦完成了对interface的实现,你需要向客户端公开该实现,这样客户端就可以使用它了。这要发布一个Service,并实现onBinder()方法来返回一个被实现的类的实例,该类继承自生成的Stub类(第二步中的mBinder)。
1 public class RemoteService extends Service { 2 3 @Override 4 public void onCreate() { 5 super.onCreate(); 6 } 7 8 @Override 9 public IBinder onBind(Intent intent) { 10 // Return the interface 11 return mBinder; 12 } 13 14 private final IRemoteService.Stub mBinder = new IRemoteService.Stub() { 15 16 public int getPid(){ 17 return Process.myPid(); 18 } 19 20 public void basicTypes(int anInt, long aLong, boolean aBoolean, 21 float aFloat, double aDouble, String aString) { 22 // Does nothing 23 } 24 }; 25 }
客户端(如其他进程的一个activity)
当一个客户端(比如一个activty调用)bindService()方法来和这个服务连接时,这个客户端的onServiceConnected() 方法接收mBinder实例并且通过Service的onBind方法返回。
客户端必须访问接口类,如果客户端和Service分属两个不同的应用,客户端应用必须复制Service的.aidl文件到他的src/ (和Service端类似,.aidl文件自动生成一个IBinder的接口并且把它保存到工程的gen文件夹下)。
当客户端在 onServiceConnected() 回调方法中接收IBinder时,它必须调用IRemoteService.Stub.asInterface(service)来与IRemoteService 接口类型保持一致。
1 IRemoteService mIRemoteService; 2 private ServiceConnection mConnection = new ServiceConnection() { 3 // Called when the connection with the service is established 4 public void onServiceConnected(ComponentName className, IBinder service) { 5 // Following the example above for an AIDL interface, 6 // this gets an instance of the IRemoteInterface, which we can use to call on the service 7 mIRemoteService = IRemoteService.Stub.asInterface(service); 8 } 9 10 // Called when the connection with the service disconnects unexpectedly 11 public void onServiceDisconnected(ComponentName className) { 12 Log.e(TAG, "Service has unexpectedly disconnected"); 13 mIRemoteService = null; 14 } 15 };