Android 接口定义语言 AIDL(Android Interface Definition Language)与其他已有的 IDL 很类似。 客户端和服务端可以通过由它定义的编程接口来达成共识,以便通过进程间通讯(IPC)完成相互通讯。 在 Android 系统中,通常一个进程不允许直接访问另一个进程的内存。 因此为了能够实现对话,进程需要把对象分解为操作系统可以识别的原生数据,在跨越进程边界后再组装起来。 实现组装的代码非常枯燥无趣,因此 Android 通过 AIDL 可有助于完成这一过程。
仅当允许其他应用程序通过 IPC 方式访问服务,并且服务需要多线程运行时,才必须用到 AIDL。

AIDL实现方法:

1.创建.aidl文件

package com.example.aidl;
interface DataService{
    int getData(String name);
}

注意,函数前面不需要public修饰符。
在编译应用程序时,会在gen/目录下生成DataService接口文件

2.服务端实现接口并向客户端公布
.aidl文件被自动生成.java接口文件。它包含一个静态子类Stub,该子类扩展了Binder类,且实现父接口。
所以,我们应该扩展Stub,并实现由.aidl文件继承的方法。

private Binder binder = new DataService.Stub() {
        @Override
        public int getData(String name) throws RemoteException {
            if(name.equals("hello")){
                return 10000;
            }
            return -1;
        }
    };

然后在onBind方法中返回该接口的实例,向客户端公布接口

public IBinder onBind(Intent intent) {
        return binder;
    }

最后在AndroidManifest.xml注册service

<service android:name="ServerService">
            <intent-filter>
                <action android:name="com.example.aidl.DataService"/>
            </intent-filter>
        </service>

这里action必须要,不然到后面会报错

server端布局文件就一个button用于启动service

server端代码结构

android aidl缺点 android aidl例子_客户端

接下来是客户端
客户端布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.aidlclient.MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="69dp"
        android:text="绑定服务" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="52dp"
        android:text="调用服务" />

</RelativeLayout>

button1的功能

button1 = (Button)findViewById(R.id.button1);
        button1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(DataService.class.getName());
                bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
            }
        });

button2后面再提

3.客户端获取接口实例
为了让客户端有权限访问接口类,客户端必须拥有一份.aidl文件的拷贝,用于生成供客户端访问AIDL方法的Binder接口。
在接收到回调方法onServiceConnected中的IBinder时,客户端必须调用DataService.Stub.asInterface(service)来把返回的参数转换为DataService类型。之后就可以使用该接口和服务端通信了。(先启动server,再启动client)

private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            dataService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            dataService = DataService.Stub.asInterface(service);
        }
    };

button2功能

button2 = (Button)findViewById(R.id.button2);
        button2.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    int result = dataService.getData("hello");
                    Log.i("test", result+"----------");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

更多详情可以参考