1.环境配置 首先将AOSP的源码编译一下,编译步骤详见传送门 
编译完成之后,查看:源码根目录/out/host/linux-x86/bin中是否有hidl-gen 工具。
配置环境变量:
1 jackou@ubuntu:~$ vim .bashrc  
 
在末尾添加
export PATH=$PATH:/home/jackou/work_directory/out/host/linux-x86/bin/
 
2.新建HIDL模块 2.1 新建hal接口文件 在hardware/interfaces目录新建存放接口的目录
 
创建hal文件,名为IHidlTest.hal
1 2 3 4 5 package  android.hardware.hidltest@1.0 ;interface  IHidlTest   {    helloWorld(string name) generates (string result); }; 
 
2.2 生成.h和.cpp文件 在根目录下利用hidl-gen生成对应的服务端代码:
1 2 3 4 PACKAGE=android.hardware.hidltest@1.0 LOC=hardware/interfaces/hidltest/1.0/default/ hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE 
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #ifndef  ANDROID_HARDWARE_HIDLTEST_V1_0_HIDLTEST_H #define  ANDROID_HARDWARE_HIDLTEST_V1_0_HIDLTEST_H #include  <android/hardware/hidltest/1.0/IHidlTest.h>  #include  <hidl/MQDescriptor.h>  #include  <hidl/Status.h>  namespace  android {namespace  hardware {namespace  hidltest {namespace  V1_0 {namespace  implementation {using  ::android::hardware::hidl_array;using  ::android::hardware::hidl_memory;using  ::android::hardware::hidl_string;using  ::android::hardware::hidl_vec;using  ::android::hardware::Return;using  ::android::hardware::Void;using  ::android::sp;struct  HidlTest  :  public  IHidlTest {         Return<void > helloWorld (const  hidl_string& name, helloWorld_cb _hidl_cb)  override  ;      };  extern  "C"  IHidlTest* HIDL_FETCH_IHidlTest (const  char * name)  ; }   }   }   }   }   #endif    
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include  "HidlTest.h"  namespace  android {namespace  hardware {namespace  hidltest {namespace  V1_0 {namespace  implementation {Return<void > HidlTest::helloWorld (const  hidl_string& name, helloWorld_cb _hidl_cb)   {         char  buf[100 ];     ::memset (buf,0x00 ,sizeof (buf));     ::snprintf (buf,100 ,"hello world, %s" ,name.c_str());     hidl_string result (buf)  ;     _hidl_cb(result);     return  Void(); } IHidlTest* HIDL_FETCH_IHidlTest (const  char * )   {    return  new  HidlTest(); } }   }   }   }   }   
 
2.3 更新bp文件 使用一下脚本更新bp文件,不知道为什么,我使用的Android P代码,lunch 10产品,使用一下脚本始终不能像博友生成Android.mk文件,只生成了Andorid.bp文件。不过没关系,不影响编译,bp文件也是可以编译的。
1 ./hardware/interfaces/update-makefiles.sh 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // Android.bp文件 // This file is autogenerated by hidl-gen -Landroidbp. hidl_interface {     name: "android.hardware.hidltest@1.0",     root: "android.hardware",     vndk: {         enabled: true,     },     srcs: [         "IHidlTest.hal",     ],     interfaces: [         "android.hidl.base@1.0",     ],     gen_java: true, } 
 
标签说明: 
name 需要与package name 相同,编译的时候会根据需要生成对应的so 或jar 
root 即为与hidl 对应的root name 
interfaces 为编译过程中依赖的接口名称,如c 中的shared library 
types 为模块中所需要的自定义类型 
如果有需要的java 代码可以将 gen_java  设为 true,如果没有(例如passthrough 模式)需要将这里设为false。不过一般通过update_makefiles.sh 就可以自动生成。详细看Android HIDL 中 hidl-gen使用  
 
配置完成之后,编译会在**~/work_directory/out/soong/.intermediates/hardware/interfaces/hidltest/1.0**生成如下文件:
2.4 采取直通模式 将HidlTest.h中的以下注释解开,代码如2.2小节
 
将HidlTest.cpp中的以下代码注解解开,代码如2.2小节
1 2 3 IHidlTest* HIDL_FETCH_IHidlTest (const  char * )   {    return  new  HidlTest(); } 
 
2.5 实现功能 在HidlTest.cpp中实现接口的功能,代码见代码如2.2小节
1 2 3 4 5 6 7 8 9 Return<void > HidlTest::helloWorld (const  hidl_string& name, helloWorld_cb _hidl_cb)   {         char  buf[100 ];     ::memset (buf,0x00 ,sizeof (buf));     ::snprintf (buf,100 ,"hello world, %s" ,name.c_str());     hidl_string result (buf)  ;     _hidl_cb(result);     return  Void(); } 
 
ok,现在大功告成; 准备开始编译。
2.6 编译模块 在根目录使用以下命令编译模块
1 mmm hardware/interfaces/hidltest/1.0/default/ 
 
具有实现的so库有了,我们开始构建binder通信服务。
在default目录创建android.hardware.hidltest@1.0-service.rc 文件,作为启动文件
1 2 3 4 service hidltest_hal_service /vendor/bin/hw/android.hardware.hidltest@1.0-service 	class hal 	user system 	group system 
 
配置服务的名字为hidltest_hal_service。
2.8 编写service文件 1 2 3 4 5 6 7 8 9 10 #define  LOG_TAG "android.hardware.hidltest@1.0-service"  #include  <android/hardware/hidltest/1.0/IHidlTest.h>  #include  <hidl/LegacySupport.h>  using  android::hardware::hidltest::V1_0::IHidlTest;using  android::hardware::defaultPassthroughServiceImplementation;int  main ()  {        printf ("start hidltest service" );         return  defaultPassthroughServiceImplementation<IHidlTest>(); } 
 
2.9 在Android.bp中添加对服务器的编译: 1 vim hardware/interfaces/hidltest/1.0/default/Android.bp 
 
在Android.bp中添加:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cc_binary {     name: "android.hardware.hidltest@1.0-service",     relative_install_path: "hw",     proprietary: true,     init_rc: ["android.hardware.hidltest@1.0-service.rc"],     srcs: ["service.cpp"],     shared_libs: [         "liblog",         "libcutils",         "libdl",         "libbase",         "libutils",         "libhardware",         "libhidlbase",         "libhidltransport",         "android.hardware.hidltest@1.0",     ], } 
 
2.10 编写manifest.xml文件 为了使客户端能够调用服务端的代码需要在manifest.xml中添加服务:在device/qcom/msm8996/manifest.xml文件最后添加:
1 2 3 4 5 6 7 8 9 10 <hal  format ="hidl" >     <name > android.hardware.hidltest</name >           <transport > passthrough</transport >      <version > 1.0</version >      <interface >      <name > IHidlTest</name >      <instance > default</instance >      </interface >  </hal > 
 
或者在车机 /vendor/etc/vintf/manifest.xml中
2.11 再次编译模块 1 mmm hardware/interfaces/hidltest/1.0/default/ 
 
最后生成的文件
out/target/product/generic_x86_64/vendor/lib64/hw/android.hardware.hidltest@1.0-impl.so 
out/target/product/generic_x86_64/vendor/bin/hw/android.hardware.hidltest@1.0-service 
out/target/product/generic_x86_64/system/lib64/vndk-28/android.hardware.hidltest@1.0.so 
 
2.12 编写C++客户端 在hardware/interfaces/hidltest/1.0/建立test目录,用于存储c++客户端代码。
创建HidlTestClient.cpp文件,并且编写客户端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include  <android/hardware/hidltest/1.0/IHidlTest.h>  #include  <hidl/Status.h>  #include  <hidl/LegacySupport.h>  #include  <utils/misc.h>  #include  <hidl/HidlSupport.h>  #include  <stdio.h>  using  ::android::hardware::hidl_string;using  ::android::sp;using  android::hardware::hidltest::V1_0::IHidlTest;int  main ()  {    android::sp<IHidlTest> service = IHIdlTest::getService();     if  (service == nullptr ){         printf ("Failed to get service\n" );         return  -1 ;     }     service->helloWorld("HidlTest" , [&](hidl_string result){     printf ("%s\n" , result.c_str());     });     return  0 ; } 
 
2.13 编写客户端编译脚本 在hardware/interfaces/hidltest/1.0/test目录下,创建Android.bp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cc_binary {     relative_install_path: "hw",     defaults: ["hidl_defaults"],     name: "hidltest_client",     proprietary: true,     srcs: ["HidlTestClient.cpp"],     shared_libs: [         "liblog",         "libhardware",         "libhidlbase",         "libhidltransport",         "libutils",         "android.hardware.hidltest@1.0",     ], } 
 
2.14 编译模块 1 mmm hardware/interfaces/hidltest/1.0/ 
 
out/target/product/generic_x86_64/system/framework/oat/x86_64/目录下生成android.hardware.hidltest-V1.0-java.odex可执行文件 
 
2.15 编写Android app端代码 2.15.1 取的jar包 从2.3中~/work_directory/out/soong/.intermediates/hardware/interfaces/hidltest/1.0/android.hardware.hidltest-V1.0-java/android_common/combined目录拿到Android端使用的jar包。
2.15.2 建立AS工程 由于HIDL调用需要java 8,所以在build.gradle中加入以下配置
1 2 3 4 5 6 7 android {     ......     compileOptions {         targetCompatibility JavaVersion.VERSION_1_8         sourceCompatibility JavaVersion.VERSION_1_8     } } 
 
2.15.3 编写代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public  class  MainActivity  extends  AppCompatActivity   {    private  static  final  String TAG = MainActivity.class.getSimpleName();     private  Button mShow;     private  TextView mTextShow;     IHidlTest mService;     @Override      protected  void  onCreate (Bundle savedInstanceState)   {         super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         mTextShow = findViewById(R.id.textView);         mShow = findViewById(R.id.button);         String content;         try  {                          mService = IHidlTest.getService();             if  (mService == null ) {                 Log.e(TAG, "service is null" );                 return ;             }             content = mService.helloWorld("hello world!" );             mTextShow.setText(content);         } catch  (RemoteException e) {             e.printStackTrace();         }                  mShow.setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)   {                 try  {                     String content = mService.helloWorld("hello world!"  + System.currentTimeMillis());                     mTextShow.setText(content);                 } catch  (RemoteException e) {                     e.printStackTrace();                 }             }         });     } } 
 
编译上面demo工程,生成apk文件,准备在目标板子上运行。
至此,所有准备工作已经做完了。 
2.16 将目标文件烧写到车机 需要准备的文件
base path: ~/work_directory/out/target/product/generic_x86_64
abstract path:
 
车机中的manifest.xml修改之后push到原来的目录
 
2.16.1 push路径说明 
android.hardware.hidltest@1.0-impl.so   –>      /vendor/lib64/hw
android.hardware.hidltest@1.0.so            –>     /system/lib64
hidltest_client                                               –>    /vendor/bin/hw
android.hardware.hidltest@1.0-service   –>    /vendor/bin/hw
manifest.xml                                               –>    /vendor/etc/vintf
 
2.16.2 安装apk
adb install -r  /本地路径/app-debug.apk
 
2.17 启动服务,测试功能 
1.启动Hidl模块服务 ./vendor/bin/hw/android.hardware.hidltest@1.0-service 
2.启动客户端 ./vendor/bin/hw/hidltest_client  
3.运行apk看界面现象
 
Notice :HAL回调实现下一小节叙述,或者见参考文献3
参考文献 1. Android HIDL 实例 
2. HIDL实战笔记 
3. Android HIDL学习(3) —- 注册回调