简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

1.前言
本篇目的:在android源码中手动生成aidl对应的java/cpp/ndk/rust语言的binder服务。
2.生成aidl对应的java服务
<1>.编写ITest.aidl
# mkdir -p aidl/com/test
# cd aidl/com/test
# emacs ITest.aidl
package aidl.com.test;
interface ITest {
	  void get(int arg);
}
注意:路径名(aidl/com/test)和包名(aidl.com.test)要一样,唯一不同是"/“和”."区分,否则编译报错。
<2>.生成ITest.aidl对应ITest.java服务文件
不指定参数,默认生成java服务文件
# aidl aidl/com/test/ITest.aidl
或者使用如下命令
# 这3条命令和上边一样,只是指定了参数
# aidl -o ./java --lang=java aidl/com/test/ITest.aidl
# tree java
java
└── aidl
    └── com
        └── test
            └── ITest.java
Or
# aidl -o ./java aidl/com/test/ITest.aidl
Or
# aidl -I ./aidl/ -o ./java aidl/com/test/ITest.aidl
注意:
-o:表示输出路径,为当前目录的java文件,它会创建一个java目录,然后在java目录中存放生成的ITest.java文件。
-I:表示依赖其他的.aidl文件。
--lang:表示支持生成的语言有哪些,如:java、cpp、ndk、rust,目前到Android12,只支持这四种语言。
# ls -al aidl/com/test/ITest.java
ITest.java
/*
 * This file is auto-generated.  DO NOT MODIFY.
 */
package aidl.com.test;
public interface ITest extends android.os.IInterface
{
  /** Default implementation for ITest. */
  public static class Default implements aidl.com.test.ITest
  {
    @Override public void get(int arg) throws android.os.RemoteException
    {
    }
    @Override
    public android.os.IBinder asBinder() {
      return null;
    }
  }
  /** Local-side IPC implementation stub class. */
  public static abstract class Stub extends android.os.Binder implements aidl.com.test.ITest
  {
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
      this.attachInterface(this, DESCRIPTOR);
    }
    /**
     * Cast an IBinder object into an aidl.com.test.ITest interface,
     * generating a proxy if needed.
     */
    public static aidl.com.test.ITest asInterface(android.os.IBinder obj)
    {
      if ((obj==null)) {
        return null;
      }
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof aidl.com.test.ITest))) {
        return ((aidl.com.test.ITest)iin);
      }
      return new aidl.com.test.ITest.Stub.Proxy(obj);
    }
    @Override public android.os.IBinder asBinder()
    {
      return this;
    }
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
    {
      java.lang.String descriptor = DESCRIPTOR;
      switch (code)
      {
        case INTERFACE_TRANSACTION:
        {
          reply.writeString(descriptor);
          return true;
        }
      }
      switch (code)
      {
        case TRANSACTION_get:
        {
          data.enforceInterface(descriptor);
          int _arg0;
          _arg0 = data.readInt();
          this.get(_arg0);
          reply.writeNoException();
          return true;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
    }
    private static class Proxy implements aidl.com.test.ITest
    {
      private android.os.IBinder mRemote;
      Proxy(android.os.IBinder remote)
      {
        mRemote = remote;
      }
      @Override public android.os.IBinder asBinder()
      {
        return mRemote;
      }
      public java.lang.String getInterfaceDescriptor()
      {
        return DESCRIPTOR;
      }
      @Override public void get(int arg) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeInt(arg);
          boolean _status = mRemote.transact(Stub.TRANSACTION_get, _data, _reply, 0);
          if (!_status) {
            if (getDefaultImpl() != null) {
              getDefaultImpl().get(arg);
              return;
            }
          }
          _reply.readException();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
      }
      public static aidl.com.test.ITest sDefaultImpl;
    }
    static final int TRANSACTION_get = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    public static boolean setDefaultImpl(aidl.com.test.ITest impl) {
      // Only one user of this interface can use this function
      // at a time. This is a heuristic to detect if two different
      // users in the same process use this function.
      if (Stub.Proxy.sDefaultImpl != null) {
        throw new IllegalStateException("setDefaultImpl() called twice");
      }
      if (impl != null) {
        Stub.Proxy.sDefaultImpl = impl;
        return true;
      }
      return false;
    }
    public static aidl.com.test.ITest getDefaultImpl() {
      return Stub.Proxy.sDefaultImpl;
    }
  }
  public static final java.lang.String DESCRIPTOR = "aidl.com.test.ITest";
  public void get(int arg) throws android.os.RemoteException;
}
3.生成aidl对应的cpp服务
还是以ITest.aidl为例子,生成对应的cpp的binder服务
# aidl -h ./aidl_cpp/ -o ./aidl_cpp --lang=cpp aidl/com/test/ITest.aidl
Or
# aidl -I ./aidl_dep -h ./aidl_cpp/ -o ./aidl_cpp --lang=cpp aidl/com/test/ITest.aidl
注意:
--lang=cpp:表示生成Android源码下编译的C++接口文件。
-o:表示.cpp文件输出路径
-h:表示.h文件输出的路径
-I:表示依赖其他*.aidl文件
# tree aidl_cpp
aidl_cpp
└── aidl
    └── com
        └── test
            ├── BnTest.h
            ├── BpTest.h
            ├── ITest.cpp
            └── ITest.h
注意:
Interface头文件:ITest.h
Bp头文件:BpTest.h
Bn头文件:BnTest.h
源码文件:ITest.cpp
4.生成aidl对应的ndk服务
还是以ITest.aidl为例子,生成对应的ndk的binder服务
# aidl -h ./aidl_ndk -o ./aidl_ndk --lang=ndk aidl/com/test/ITest.aidl
# tree aidl_ndk
aidl_ndk
└── aidl
    ├── aidl
    │   └── com
    │       └── test
    │           ├── BnTest.h
    │           ├── BpTest.h
    │           └── ITest.h
    └── com
        └── test
            └── ITest.cpp
5.生成aidl对应的rust服务(因为Android已经支持Rust语言开发)
Rust是一个跨平台开发语言,支持Android,iOS,桌面,Web和后端的开发。
 还是以ITest.aidl为例子,生成对应的Rust的binder服务
# aidl -o ./aidl_rust --lang=rust aidl/com/test/ITest.aidl
# tree aidl_rust
aidl_rust/
└── aidl
    └── com
        └── test
            └── ITest.rs
6.在Android.bp中自动生成aidl对应的java/cpp/ndk/rust服务
Android.bp
aidl_interface {
    name: "Test",
    srcs: [ "aidl/com/test/*.aidl", ],
    unstable: true,
    backend: {
        java: {
            enabled: false,
            platform_apis: true,
        },
        cpp: {
            enabled: false,
        },
        ndk: {
            enabled: true,
            vndk: {
                enabled: false,
            },
        },
    //Android12才支持编译aidl对应Rust服务
        rust: {
             enabled: true,
        },
    },
}
注意:编译aidl对应哪个语言支持,将enabled设置为:true,如果不想生成则设置为:false。



















