安卓接口语言 Android Interface Definition Language (AIDL)

翻译作者地址:http://su1216.iteye.com/%20http://blog.csdn.net/su1216/

AIDL一般都用在需要比较复杂的跨进程/线程通信场合。比如自己的程序需要用一个Service去处理各种事务,而又需要跟Service能相互调用的场合。要注意的是AIDL不是线程安全的,如有这方面需要的话就要自己处理好临界情况。

使用AIDL只有在你允许来自不同应用的客户端跨进程通信访问你的service,并且想要在你的service种处理多线程的时候才是必要的。 如果你不需要执行不同应用之间的IPC并发,你应该通过实现Binder建立你的接口,或者如果你想执行IPC,但是不需要处理多线程。那么使用Messenger实现你的接口 不管怎样,确保你在实现一个AIDL之前理解了Bound Service

下面以客户端A应用调用B应用为例

1.定义一个AIDL接口

创建一个以.aidl结尾的文件。打开创建的文件,使用java语言定义一个接口,接口只包含接口声明和方法签名。如下
// IRemoteService.aidl
package com.example.android;
/** Example service interface */
interface IRemoteService {
   //接口声明
    int getPid();
    //方法声明(方法可以接收0或多个参数,并且有返回值或者返回void)
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat);
}

保存.aidl文件在src目录下

2.实现接口

当你编译你的应用时,Android SDK工具生成一个.java接口文件用你的.aidl文件命名 生成的接口包含一个名字为Stub的子类(比如YourInterface.Stub),这是一个它父类的抽象实现,并且声明了.aidl中所有的方法

//IRemoteService.Stu是IBinder的子类
private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
    public int getPid(){
        return Process.myPid();
    }
    public void basicTypes(int anInt, long aLong, boolean aBoolean,
        float aFloat, double aDouble, String aString) {
        // Does nothing
    }
};

3.暴露接口给客户端

一旦你为service实现了接口,你需要把它暴露给客户端,这样他们才能绑定到上面 为了给你的service暴露接口,继承Service并且实现onBind()方法返回一个你实现生成的Stub类(像我们在上一结讨论的那样) 这有一个service暴露IRemoteService接口给客户端的例子

public class RemoteService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Return the interface
        return mBinder;
    }

    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() 
   {
        public int getPid(){
            return Process.myPid();
                           }
        public void basicTypes(int anInt, long aLong, boolean aBoolean,
            float aFloat, double aDouble, String aString) {
            // Do something(执行逻辑)
        }
    };
}

在B应用的manifes中,service的相关配置片段

<service android:name="com.zhangxikai.RemoteService">
            <intent-filter >
                <action android:name="com.zahngxikai.aidl"/>
            </intent-filter>
</service>

通过以上三步我们完成了被调用端B的工作。

现在,当一个客户端(比如一个activity)调用bindService()来连接到这个service,这个客户端的onServiceConnected()回调函数接收service中onBind()方法返回的mBinder实例

客户端必须可以访问接口类,所以如果客户端和服务端在不同的应用中,那么客户端所在的应用必须有一份.aidl文件的副本在其src目录下(生成android.os.Binder接口,提供客户端访问AIDL方法都在这个目录下)

当客户端在onServiceConnected()回调方法中接收到IBinder时,它必须调用你的ServiceInterface.Stub.asInterface(service)来把返回参数映射到你的ServiceInterface类型上。例如:

IRemoteService mIRemoteService;
private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
    //获取接口
        mIRemoteService = IRemoteService.Stub.asInterface(service);
    }
    public void onServiceDisconnected(ComponentName className) {
        Log.e(TAG, "Service has unexpectedly disconnected");
        mIRemoteService = null;
    }
};
在A应用中调用B应用的basicTypes方法
Intent intent = new Intent();
intent.setAction("com.zahngxikai.aidl");
bindService(intent,mConnection,BIND_AUTO_CREATE);
//调用B应用中的相关函数(最终目的)
mIRemoteService.basicTypes(....参数);

Android中文api原文地址:这里写链接内容

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值