AIDL(Android Interface Definition LanguageAndroid接口定义语言)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AIDL(Android Interface Definition LanguageAndroid接口定义语言)相关的知识,希望对你有一定的参考价值。

1.什么是AIDL

android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。
 

2.建立AIDL服务的步骤

建立AIDL服务要比建立普通的服务复杂一些,具体步骤如下:
(1)在Eclipse Android工程的Java包目录中建立一个扩展名为aidl的文件。该文件的语法类似于Java代码,但会稍有不同。
(2)如果aidl文件的内容是正确的,ADT会自动生成一个Java接口文件(*.java)。
(3)建立一个服务类(Service的子类)。
(4)实现由aidl文件生成的Java接口。
(5)在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。
 
 
 
通常每个应用程序都在他自己的进程内运行,但有时需要在进程之间传递对象(IPC通信)。此时可以通过应用程序UI的方式写一个运行在不同进程中的service。在Android平台中,一个进程通常不能访问其他进程中的内存区域。所以它们需要把对象拆分成操作系统能理解的简单形式,以便伪装成对象跨边界访问。而要完成这些需要AIDL机制。

        AIDL(Android接口描述语言)是一个IDL语言,它可以生成一段代码,可以是一个在Android设备上运行的两个进程使用内部通信进程进行交互。如果你想在一个进程中(例如在一个Activity中)访问另一个进程中(例如service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。

        要使用AIDL,service需要以AIDL文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务器接口中包含一个功能调用的stub()服务桩类。service的onBind方法会返回实现类的对象,之后你就可以使用它了。

        AIDL文件

        framework中包含的aidl是在frameworks/base/Android.mk中定义的。该文件定义了两处aidl文件列表。

        第一处是给LOCAL_SRC_FILES变量中使用 “+=” 进行赋值,该变量将包含在framework.jar目标中的所有源文件,包括aidl文件和java文件。

        第二处是给aidl_files变量使用“:=”赋值符号进行赋值,该变量仅仅包含android.jar目标中所有的aidl文件。

        因此,当给Frameworks中添加新的aidl文件时,需要考虑文件是否要公开到SDK中。如果需要,则需要把该文件路径同时添加到以上两个变量中;如果不需要公开到SDK中,则只需要把文件路径添加到LOCAL_SRC_FILES变量中。

 

      在完成这些操作后编译仍会出现问题,此时需要运行,make update-api命令,此时改变的文件是current.txt改变的内容如下:

+  public abstract interface IEneaService implements android.os.IInterface {

+  }

+

+  public static abstract class IEneaService.Stub extends android.os.Binder implements android.os.IEneaService {

+    ctor public IEneaService.Stub();

+    method public android.os.IBinder asBinder();

+    method public static android.os.IEneaService asInterface(android.os.IBinder);

+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;

+  }

+

        这时,如果希望在写的Activity中使用的情况下,需要首先获取服务,这个步骤是通过"ServiceManager.getService()"这个API实现。然后使用service handle来调用service暴露出来的函数。ITestService om = ITestService.Stub.asInterface(ServiceManager.getService("Test"));

       下面是个简单的例子:

 

/*
* HelloServer.java
*/
package com.Test.helloserver;
import android.app.Activity;
import android.os.Bundle;
import android.os.ServiceManager;
import android.os.ITestService;
import android.util.Log;
public class HelloServer extends Activity {
    private static final String DTAG = "HelloServer";
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ITestService om = ITestService.Stub.asInterface(ServiceManager.getService("Test"));
        try {
			    Log.d(DTAG, "Going to call service");
			    om.setValue(20);
			    Log.d(DTAG, "Service called succesfully");
        }
        catch (Exception e) {
			    Log.d(DTAG, "FAILED to call service");
    			e.printStackTrace();
        }
    }
}

以上是关于AIDL(Android Interface Definition LanguageAndroid接口定义语言)的主要内容,如果未能解决你的问题,请参考以下文章

AIDL(Android Interface Definition LanguageAndroid接口定义语言)

Android中AIDL的使用

android AIDL 实践之传递简单字串

Android AIDL(安卓接口定义语言)基本使用方法

Android AIDL(安卓接口定义语言)基本使用方法

HIDL(HAL interface definition langguage)