AIDL文件在Android系統(tǒng)上應(yīng)用廣泛,和底層的Binder機(jī)制緊密關(guān)聯(lián)。
在Android源碼或者Android Studio中通常是自動(dòng)編譯aidl文件,生成對(duì)應(yīng)語(yǔ)言的接口文件。
做應(yīng)用層Java開(kāi)發(fā),aidl和binder封裝的比較“干凈”,不用太多的涉及binder的調(diào)用細(xì)節(jié),也不用太關(guān)心aidl的編譯過(guò)程。
如果是做中下層開(kāi)發(fā),包括framework、native層開(kāi)發(fā),可能需要編寫(xiě)native service,有必要理解binder的底層機(jī)制。
先從編譯aidl開(kāi)始。這里只說(shuō)明編譯aidl生成各種類(lèi)型后端接口文件的過(guò)程。生成的接口文件內(nèi)容再寫(xiě)文章單獨(dú)介紹。
以下演示是在Ubuntu系統(tǒng)上測(cè)試的。
一、準(zhǔn)備
1. aidl編譯工具
即aidl命令,Android sdk或者Android源碼中都有。
sdk中aidl,需要把路徑添加到path中。
位置:~/Android/Sdk/build-tools/33.0.2/aidl
源碼中aidl,設(shè)置源碼編譯環(huán)境后,自動(dòng)添加到path中。
位置:out/soong/host/linux-x86/bin/aidl
2. 演示用的aidl文件
寫(xiě)2個(gè)簡(jiǎn)單的aidl文件,一個(gè)是服務(wù)接口,一個(gè)是回調(diào)接口??捎酶采w大部分的實(shí)際場(chǎng)景。
文件目錄結(jié)構(gòu)和文件內(nèi)容如下。
$ tree .
.
└── aidl
└── com
└── my
└── pkg
├── IMyServiceCallback.aidl
└── IMyServiceInterface.aidl
回調(diào)接口定義:
// IMyServiceCallback.aidl
package com.my.pkg;
interface IMyServiceCallback {
void onEvent(int code, String message);
}
服務(wù)接口定義:
// IMyServiceInterface
package com.my.pkg;
interface IMyServiceInterface {
int doSomething(in String str, int num);
void setCallBack(com.my.pkg.IMyServiceCallback callback);
}
二、生成Java接口
執(zhí)行如下命令,生成Java接口文件。
說(shuō)明:
- aidl使用說(shuō)明
aidl --lang={java|cpp|ndk} [options] input_aidl_file。
在命令行中,aidl不帶任何參數(shù),打印使用說(shuō)明。 - –lang={java|cpp|ndk}
指定生成接口類(lèi)型。如果不指定,默認(rèn)生成Java文件。 - -o 指定輸出目錄
Java:省略-o參數(shù),java文件生成到aidl文件目錄下。
C++/Rust:必選參數(shù)。
為了清除查看效果,指定到單獨(dú)的目錄:-o ./java - -I DIR, --include=DIR
import搜索路徑,指定依賴(lài)的aidl文件所在目錄。不是C++頭文件目錄。
例如:IMyServiceInterface.aidl引用了IMyServiceCallback.aidl,在生成IMyServiceInterface.aidl的時(shí)候需要指定-I參數(shù)才能正常編譯。
只要是AIDL文件中有依賴(lài),生成任何類(lèi)型的接口(Java、C++、Rust)都要指定這個(gè)參數(shù)。
# 前2條命令效果相同,不指定--lang參數(shù),默認(rèn)生成Java文件
$ aidl -o ./java --lang=java aidl/com/my/pkg/IMyServiceCallback.aidl
$ aidl -o ./java aidl/com/my/pkg/IMyServiceCallback.aidl
$ aidl -I ./aidl/ -o ./java aidl/com/my/pkg/IMyServiceInterface.aidl
$ tree
.
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── IMyServiceCallback.aidl
│ └── IMyServiceInterface.aidl
└── java
└── com
└── my
└── pkg
├── IMyServiceCallback.java
└── IMyServiceInterface.java
三、生成C++[Android]接口
-
cpp和ndk的區(qū)別
cpp:生成的代碼是為了在Android源碼中編譯,代碼中會(huì)調(diào)用Android源碼中的native接口。
例如,引用的頭文件:
<binder/IBinder.h>,<binder/IInterface.h>,<binder/Status.h>,<android-base/macros.h>ndk:生成的代碼是為了使用ndk獨(dú)立編譯,調(diào)用的是ndk的接口,
例如,引用的頭文件:
<android/binder_interface_utils.h> <android/binder_ibinder.h> -
–lang=cpp,參數(shù)指定生成Android源碼下編譯的C++接口文件。
-
-o和-h參數(shù)分別指定.cpp文件和.h文件輸出的路徑??梢灾付ú煌哪夸?。
1)C++接口文件比較多,一個(gè)aidl文件生成4個(gè)文件。第一步編譯IMyServiceCallback.aidl后,生成文件包括:
3個(gè)頭文件:
一個(gè)Interface頭文件:IMyServiceCallback.h
一個(gè)Bp頭文件:BpMyServiceCallback.h
一個(gè)Bn頭文件:BnMyServiceCallback.h
一個(gè)源碼文件:IMyServiceCallback.cpp文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-478191.html
$ aidl -h ./cpp_android/ -o ./cpp_android --lang=cpp aidl/com/my/pkg/IMyServiceCallback.aidl
$ tree
.
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── IMyServiceCallback.aidl
│ └── IMyServiceInterface.aidl
└── cpp_android
└── com
└── my
└── pkg
├── BnMyServiceCallback.h
├── BpMyServiceCallback.h
├── IMyServiceCallback.cpp
└── IMyServiceCallback.h
$ aidl -I ./aidl/ -h ./cpp_android/ -o ./cpp_android --lang=cpp aidl/com/my/pkg/IMyServiceInterface.aidl
$ tree
.
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── IMyServiceCallback.aidl
│ └── IMyServiceInterface.aidl
└── cpp_android
└── com
└── my
└── pkg
├── BnMyServiceCallback.h
├── BnMyServiceInterface.h
├── BpMyServiceCallback.h
├── BpMyServiceInterface.h
├── IMyServiceCallback.cpp
├── IMyServiceCallback.h
├── IMyServiceInterface.cpp
└── IMyServiceInterface.h
四、生成C++[ndk]接口
除了–lang=ndk指定生成ndk后端接口,過(guò)程和結(jié)果都和cpp類(lèi)似。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-478191.html
$ aidl -I ./aidl/ -h ./cpp_ndk -o ./cpp_ndk --lang=ndk aidl/com/my/pkg/IMyServiceInterface.aidl
$ aidl -h ./cpp_ndk -o ./cpp_ndk --lang=ndk aidl/com/my/pkg/IMyServiceCallback.aidl
$ tree cpp_*
cpp_android
└── com
└── my
└── pkg
├── BnMyServiceCallback.h
├── BnMyServiceInterface.h
├── BpMyServiceCallback.h
├── BpMyServiceInterface.h
├── IMyServiceCallback.cpp
├── IMyServiceCallback.h
├── IMyServiceInterface.cpp
└── IMyServiceInterface.h
cpp_ndk
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── BnMyServiceCallback.h
│ ├── BnMyServiceInterface.h
│ ├── BpMyServiceCallback.h
│ ├── BpMyServiceInterface.h
│ ├── IMyServiceCallback.h
│ └── IMyServiceInterface.h
└── com
└── my
└── pkg
├── IMyServiceCallback.cpp
└── IMyServiceInterface.cpp
五、生成Rust接口文件
- –lang=rust指定生成rust后端接口文件。
- 只需通過(guò)-o參數(shù)設(shè)置輸出路徑即可,輸出結(jié)果和Java類(lèi)似,一個(gè)aidl文件對(duì)應(yīng)一個(gè).rs文件。
- Rust后端是比較新版本的aidl才支持的,可能是Android 12以后,可以查看aidl命令幫助確認(rèn)。
$ aidl -o ./rust --lang=rust aidl/com/my/pkg/IMyServiceCallback.aidl
$ aidl -I ./aidl/ -o ./rust --lang=rust aidl/com/my/pkg/IMyServiceInterface.aidl
$ tree
.
├── aidl
│ └── com
│ └── my
│ └── pkg
│ ├── IMyServiceCallback.aidl
│ └── IMyServiceInterface.aidl
└── rust
└── com
└── my
└── pkg
├── IMyServiceCallback.rs
└── IMyServiceInterface.rs
到了這里,關(guān)于[Android AIDL系列 1] 手動(dòng)編譯aidl文件,生成Java、C++[android]、C++[ndk]、Rust接口的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!