- 论坛徽章:
- 80
|
一.基础知识
AIDL的作用
在Android平台,每个应用程序App都运行在自己的进程空间。通常一 个进程不能访问另一个进程的内存空间(一个应用不能访问另一个应用),如果想沟通,需要将对象分解成操作系统可以理解的基本单元,Android提供了AIDL来处理。
AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参 数。换句比较浅显的话来说,就是我这个App应用的activity,需要调用其他App应用的Service.当然同一App应用的activity 与service也可以在不同进程间,这可以设置Service配置中,android:process=":remote"
AIDL的使用
官方文档特别提醒我们何时使用AIDL是必要的:只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的service,以及想在你的service处理多线程。(太生硬了,不同进程的组件调用吧。)
那么怎么制作AIDL呢?下面步骤
1:创建.aidl文件。新建立个文件并且以.aidl作为后缀保存,在这个文件中编写接口以及方法,这个我们普通java接口声明是一样的,不同的是要显示import 复杂类型,即便复杂类型对象在同一个包内。Java基本数据类型 (int, long, char, boolean等),String和CharSequence,集合接口类型List和Map,不需要import 。
比如:
package com.dongzi;
interface IStockQuoteService{
double getPrice(String ticker);
}
2:创建好AIDL文件后,刷新下工程,你会发现在gen包下,对应的包下面出现一个与AIDL文件相同的java文件。如:- /*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: D:\\mywordspace\\MyPhone\\src\\com\\dongzi\\IStockQuoteService.aidl
- */
- package com.dongzi;
- public interface IStockQuoteService extends android.os.IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements com.dongzi.IStockQuoteService {
- private static final java.lang.String DESCRIPTOR = "com.dongzi.IStockQuoteService";
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an com.dongzi.IStockQuoteService
- * interface, generating a proxy if needed.
- */
- public static com.dongzi.IStockQuoteService asInterface(android.os.IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- android.os.IInterface iin = (android.os.IInterface) obj.queryLocalInterface(DESCRIPTOR);
- if (((iin != null) && (iin instanceof com.dongzi.IStockQuoteService))) {
- return ((com.dongzi.IStockQuoteService) iin);
- }
- return new com.dongzi.IStockQuoteService.Stub.Proxy(obj);
- }
- public android.os.IBinder asBinder() {
- return this;
- }
- @Override
- public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
- throws android.os.RemoteException {
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_getPrice: {
- data.enforceInterface(DESCRIPTOR);
- java.lang.String _arg0;
- _arg0 = data.readString();
- double _result = this.getPrice(_arg0);
- reply.writeNoException();
- reply.writeDouble(_result);
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- private static class Proxy implements com.dongzi.IStockQuoteService {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote) {
- mRemote = remote;
- }
- public android.os.IBinder asBinder() {
- return mRemote;
- }
- public java.lang.String getInterfaceDescriptor() {
- return DESCRIPTOR;
- }
- public double getPrice(java.lang.String ticker) throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- double _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(ticker);
- mRemote.transact(Stub.TRANSACTION_getPrice, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readDouble();
- }
- finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
- }
- static final int TRANSACTION_getPrice = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
- }
- public double getPrice(java.lang.String ticker) throws android.os.RemoteException;
- }
复制代码 AIDL工具自动生成了那么多代码,其实我们只需要知道3个就够了。
public static abstract class Stub extends android.os.Binder implements com.dongzi.IStockQuoteService 静态抽象内部类Stub
private static class Proxy implements com.dongzi.IStockQuoteService AIDL服务代理类
public double getPrice(java.lang.String ticker) throws android.os.RemoteException; AIDL公布出的接口,就是我们定义的接口方法
3:把AIDL文件存放在其他客户端应用中,我们这个作为服务端。当然我们也可以方便的把这个应用作为客户端以及服务端。其实根本区别就是为了使调用者与被调用者在不同进程中,于是在服务中添加android:process=":remote"即可。省去了再建立应用客户端调用。
4:AIDL只是请定义一个契约,我们这里需要一个服务来提供服务。于是建立服务MyService. |
|