这可能是最简单aidl例子了

832 阅读2分钟

什么是aidl?

AIDL:Android Interface Definition Language,即Android接口定义语言。

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)服务。

demo所用到的:

1.server端。

说白了就是一个应用,作为被调用方,挂起一个serivce,在service的onBind回调中返回一个IBinder对象,IBinder对象来自于aidl编译后产生的对应IMyAidlInterface.java的对象的Stub方法,然后再实现aidl定义的接口即可。

//文件路径:./MyApplication2/app/src/main/java/com/example/myapplication2/MyService.java
public class MyService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private Binder mBinder = new IMyAidlInterface.Stub() {
        @Override
        public int sum(int a, int b) throws RemoteException {
            return a + b - 1;
        }
    };
}

----------- 

//文件路径:./MyApplication2/app/src/main/aidl/com/example/myapplication2/IMyAidlInterface.aidl
//注意!!!IMyAidlInterface.aidl的路径是在aidl目录底下
package com.example.myapplication2;

interface IMyAidlInterface {
    int sum(int a, int b);
}

当然,这里还需要把service挂起。就是在activity中startService,这里不展示代码了。

可以通过adb shell dumpsys activity services com.example.myapplication2

贴一下AndroidManifest.xml中MyService的声明

<!--需要设置exported为true,将service暴露出去-->
<service android:name=".MyService"
   android:exported="true" />

2.client端。

客户端同样是一个应用,作为调用方。所需要做的就是把客户端的aidl文件copy一份到自己的项目中。

然后bindService,在服务已连接的回调中拿到IBinder对象作为IMyAidlInterface.Stub.asInterface的入参,可获得IMyAidlInterface对象,调用接口定义的方法sum(int a, int b)即完全aidl流程。

int result = aidlInterface.sum(1, 1);

返回result为1,验证成功。

package com.example.myapplication;
//...
import com.example.myapplication2.IMyAidlInterface;
//注意!!!这里客户端的包名是com.example.myapplication,
//import的IMyAidlInterface包名是com.example.myapplication2。

@Override
protected void onStart() {
    super.onStart();
    Intent intent = new Intent();
    intent.setPackage("com.example.myapplication2");
    intent.setComponent(new ComponentName("com.example.myapplication2",
        "com.example.myapplication2.MyService"));
    bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unbindService(mServiceConnection);
}

private ServiceConnection mServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        IMyAidlInterface aidlInterface = IMyAidlInterface.Stub.asInterface(service);
        try {
            int result = aidlInterface.sum(1, 1);
            Log.e("qinbin", "aidl success,result = " + result);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.e("qinbin", "onServiceDisconnected");
    }
};