当前位置:操作系统 > 安卓/Android >>

Android Inte易做图ce Definition Language (AIDL)

Android Inte易做图ce Definition Language (AIDL)
IN THIS DOCUMENT
Defining an AIDL Inte易做图ce
Create the .aidl file
Implement the inte易做图ce
Expose the inte易做图ce to clients
Passing Objects over IPC
Calling an IPC Method
SEE ALSO
Bound Services
AIDL (Android Inte易做图ce Definition Language) 与其他的接口定义语言相似。定义这个接口,client 和service 可以通过这个接口在进程之间进行通信。所以说,对象要能在进程之间传递,就需要将对象分解成系统能识别的指令。通过代码实现那个是非常的冗长乏味的,android 系统通过AIDL可以处理。

Note: 希望从不同的应用中访问service,并且在service需要处理多线程,这种情况下才会使用AIDL。如果不需要从其他的应用中处理IPC,那么可以实现Binder;如果需要IPC,但是不需要处理多线程,那么可以使用Messenger。在使用之前,先考虑好哪种方式是适合自己的。

设计AIDL接口之前,需要确认AIDL接口里面该有的方法。不能假设当调用发生时,thread会伴随。发生什么是不同的,取决于该调用是从本地进程或远程进程的线程发起的。具体来讲:


在本地进程中的同一个线程发起调用请求。如果这是你的主UI线程,线程继续在AIDL接口上执行。如果是其他的线程,它会在service中运行代码。如果仅仅是本地线程访问service,可以控制具体的线程在service中执行(如果是在这种情况下,不需要使用AIDL,可以用Binder方式代替).
从远程进程的线程池中发起调用。需要准备好处理不知线程的同时发起的调用。换句话说,实现AIDL必须保证所有线程的安全性。
The oneway keyword modifies the behavior of remote calls. When used, a remote call does not block; it simply sends the transaction data and immediately returns. The implementation of the inte易做图ce eventually receives this as a regular call from the Binder thread pool as a normal remote call. If oneway is used with a local call, there is no impact and the call is still synchronous.
Defining an AIDL Inte易做图ce

--------------------------------------------------------------------------------

可以用Java编程语言的语法定义AIDL接口,文件保存在源代码(src/)下,当前应用拥有这个service并且,其他的应用可以绑定这个service。

当构建的应用中含有.aidl文件,Android SDK 工具根据.aidl文件能够生成一个IBinder的接口,保存在项目的gen/目录。service应该合理的实现IBinder接口。client 应用可以绑定这个service,并通过IBinder调用service的方法。

用AIDL创建一个绑定的service,基本步骤如下:

创建.aidl文件
这个文件定义了接口和方法.

实现接口
Android SDK 工具基于.aidl文件能够生成一个接口。接口里面含有一个名字为Stub的抽象内部类,并且实现了AIDL接口中定义的方法。使用的时候,必须继承Stub类,实现它的方法。

公开接口
实现service,重写onBind(), 它的返回值是stub类。

Caution: 对AIDL接口做的任何改变,必须向后兼容,避免其他使用service的应用无法继续工作。也就是说,因为这个.aidl文件必须复制到其他的应用中,为了能访问这个service的接口,必须保证对原始接口的支持。

1. 创建.aidl文件
AIDL 使用简单的语法定义接口,可以有一个或者多个方法,这些方法可以传入参数和返回值。参数和返回值可以是任何类型,甚至其他aidl生成的接口。

.aidl文件必须使用java语法,每一个.aidl文件只能定义一个单独的接口,并且只需要接口的声明和方法的声明。

一般情况,AIDL支持一下数据类型:

所有的java基本类型 (例如 int, long, char, boolean, 等等)
String
CharSequence
List
List中所有的元素必须是AIDL支持的类型,或者是其他的AIDL接口和定义的parcebles.一个List可以被用来作为一个通常类(例如,List<String>). 实际具体的类接到总是一个ArrayList,虽然该方法生成的时候是List 接口.

Map
Map中所有的元素必须是AIDL支持的类型,或者是其他的AIDL接口和定义的parcebles.通常的Map(例如Map<String,Integer>这种形式的Map是不支持的)。实际具体的类接到总是一个HashMap,虽然该方法生成的时候是Map 接口.

当要导入的类型,上面没有列举,需要import, 即使它们定义在和当前AIDL文件相同的包里面。

当定义service的接口时,要意识到:

方法可以有0个或者多个参数,可以返回一个值或者是void.
All non-primitive parameters require a directional tag indicating which way the data goes. Either in, out, orinout (see the example below).
Primitives are in by default, and cannot be otherwise.

Caution: 必须考虑真正需要的数据方向,因为数据装换是非常昂贵的。

包含在.aidl中所有的注释在IBinder接口中都会生成(除了在import和package之前的注释)
仅仅支持方法,不支持静态的成员变量。
下面上.aidl 文件的例子:

// IRemoteService.aidl
package com.example.android;

// Declare any non-default types here with import statements

/** Example service inte易做图ce */
inte易做图ce IRemoteService {
    /** Request the process ID of this service, to do evil things with it. */
    int getPid();

    /** Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}将.aidl文件保存在 src/ 目录下,当编译项目的时候,, SDK tools 生成IBinder接口文件,放在项目的gen/ 目录里面.

如果您使用的是Eclipse,会迅速的生成Binder类。如果您没有使用Eclipse,Ant tool 可以在下次构建应用的时候,自动生成binder 类-构建项目的时候需要ant debug (或者ant release), 在写好.aidl文件的时候就构建一个次,以便在编码的时候可以引用生成的类。

2. 实现接口
当您构建项目的时候,Android SDK 工具会生成一个java 接口文件。 生成的接口文件中包含一个Stub 的内部抽象类,这个类实现在.aidl中定义的方法。

Note: Stub 同样定义了一些帮组的方法,最特别的是 asInte易做图ce(), 它需要一个IBinder(通常传递给客户的onServiceConnected()回调方法), 并且返回一个stub接口的实例。See the section Calling an IPC Method for more details on how to make this cast.

要实现从.aidl文件中生成出来的接口,继承生成的Binder接口(例如,YourInte易做图ce.Stub),并且实现从.aidl文件中继承来的方法。

这里是一个通过匿名类的方式实现IRemoteService 接口的例子:

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
    }
};现在mBinder是Stub类的一个实例,下一步,这个接口需要暴露给client调用。

这里是实现AIDL接口的一些规则:

不能保证是从主线程里发起的调用,因此在使用的时候,需要考虑多线程启动和保证service运行时的线程安全性。
默认情况,远程调用是同步的。如果你知道你的service完成的任务需要一些时间,不能从activity的主线程中调用service,因为这样调用会导致application挂起(应用等待响应),最好在一个新的线程中调用。
Service不会返回任何开发者自己抛出的异常到调用者。
3. 把接口公开给客户端
一旦service实现了接口,然后要把它暴露给client,以便clients绑定它。为service公开接口,继承Service和实现onBind()并返回实现Stub类的实例.下面的service例子公开IRemoteService 接口给clients.

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

    @Override
    public IBinder onBind(Intent intent) {
        // Return the inte易做图ce
        return mBinder;
    }

    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
        public int getPid(){
            return Process.myPid();
        }
    &nb

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,