刚接触android 的hidl,项目中要用到,就尝试写了一个简单的实例。

一、定义HIDL接口文件

1.进入hardware/interfaces/目录下建立新的接口文件

首先建立对应的文件夹:android/hardware/interfaces/sample/1.0/default

接着在android/hardware/interfaces/sample/1.0/目录创建接口描述文件ISample.hal

android/hardware/interfaces/sample/1.0/ISample.hal内容如下:

package android.hardware.sample@1.0;interface ISample {helloWorld(string name) generates (string result);init();
};

2.通过hidl-gen工具(源码中编译生成hidl-gen)生成Sample.cpp,Sample.h ,Android.bp文件。 步骤如下:

1.source build/envsetup.sh
2.lunch 9            (根据自己的项目选)
3.export PACKAGE=android.hardware.sample@1.0      //设置变量
4.export LOC=hardware/interfaces/sample/1.0/default/   //设置变量生成目录的所在地
5.hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE//在hardware/interfaces/sample/1.0/default/生成Sample.cpp和Sample.h
6.hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
//在hardware/interfaces/sample/1.0/default/生成Android.bp
7.在android目录下执行 ./hardware/interfaces/update-makefiles.sh在hardware/interfaces/sample/1.0/目录下生成Android.bp

这时文件目录结构如下

@user-virtual-machine:~/android/hardware/interfaces/sample$ ls 1.0/
Android.bp  default  ISample.hal
@user-virtual-machine:~/android/hardware/interfaces/sample$ ls 1.0/default/
Android.bp    Sample.cpp  Sample.h

生成的代码如下:

3.android/hardware/interfaces/sample/1.0/default/Sample.h

去掉注释.采用直通模式

//extern "C" ISample* HIDL_FETCH_ISample(const char* name);
android/hardware/interfaces/sample/1.0/default/Sample.h内容如下#ifndef ANDROID_HARDWARE_SAMPLE_V1_0_SAMPLE_H
#define ANDROID_HARDWARE_SAMPLE_V1_0_SAMPLE_H#include <android/hardware/sample/1.0/ISample.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>namespace android {
namespace hardware {
namespace sample {
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 Sample : public ISample {// Methods from ::android::hardware::sample::V1_0::ISample follow.Return<void> helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) override;Return<void> init() override;// Methods from ::android::hidl::base::V1_0::IBase follow.};// FIXME: most likely delete, this is only for passthrough implementationsextern "C" ISample* HIDL_FETCH_ISample(const char* name);}  // namespace implementation
}  // namespace V1_0
}  // namespace sample
}  // namespace hardware
}  // namespace android#endif  // ANDROID_HARDWARE_SAMPLE_V1_0_SAMPLE_H

4.android/hardware/interfaces/sample/1.0/default/Sample.cpp

//ISample* HIDL_FETCH_ISample(const char* /* name */) {
//    return new Sample();
//}

去掉上面的注释

android/hardware/interfaces/sample/1.0/default/Sample.cpp内容如下#include "Sample.h"
namespace android {
namespace hardware {
namespace sample {
namespace V1_0 {
namespace implementation {// Methods from ::android::hardware::sample::V1_0::ISample follow.
Return<void> Sample::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {// TODO implementreturn Void();
}Return<void> Sample::init() {// TODO implementreturn Void();
}// Methods from ::android::hidl::base::V1_0::IBase follow.ISample* HIDL_FETCH_ISample(const char* /* name */) {return new Sample();
}
//
}  // namespace implementation
}  // namespace V1_0
}  // namespace sample
}  // namespace hardware
}  // namespace android

5.上面大部分都是通过hidl工具生成的,下面完善一下接口代码。

android/hardware/interfaces/sample/1.0/default/Sample.cpp#include "Sample.h"
#define LOG_TAG "xingchen"
#include <log/log.h>
namespace android {
namespace hardware {
namespace sample {
namespace V1_0 {
namespace implementation {// Methods from ::android::hardware::sample::V1_0::ISample follow.
Return<void> Sample::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {// TODO implementchar buf[128];::memset(buf,0,128);::snprintf(buf,128,"Hello World,%s",name.c_str());hidl_string result(buf);_hidl_cb(result);//ALOGI("xingchen helloWorld Sample:: ___%s__",__fun__);ALOGI("xingchen helloWorld Sample::----");return Void();
}Return<void> Sample::init() {// TODO implement//ALOGI("xingchen Sample:: ___%s__",__fun__);ALOGI("xingchen Sample::---");return Void();
}// Methods from ::android::hidl::base::V1_0::IBase follow.ISample* HIDL_FETCH_ISample(const char* /* name */) {return new Sample();
}
//
}  // namespace implementation
}  // namespace V1_0
}  // namespace sample
}  // namespace hardware
}  // namespace android

6.android/hardware/interfaces/sample/1.0/default/Android.bp

android/hardware/interfaces/sample/1.0/default/Android.bp内容如下cc_library_shared {// FIXME: this should only be -impl for a passthrough hal.// In most cases, to convert this to a binderized implementation, you should:// - change '-impl' to '-service' here and make it a cc_binary instead of a//   cc_library_shared.// - add a *.rc file for this module.// - delete HIDL_FETCH_I* functions.// - call configureRpcThreadpool and registerAsService on the instance.// You may also want to append '-impl/-service' with a specific identifier like// '-vendor' or '-<hardware identifier>' etc to distinguish it.name: "android.hardware.sample@1.0-impl",relative_install_path: "hw",// FIXME: this should be 'vendor: true' for modules that will eventually be// on AOSP.proprietary: true,srcs: ["Sample.cpp",],shared_libs: ["libhidlbase","libhidltransport","libhardware","libutils","liblog","android.hardware.sample@1.0",],
}

7.到这里基本上代码就写完了,大部分都是生成的,下面开始编译.

 mmm hardware/interfaces/sample/1.0/default/ 生成库文件
/vendor/lib64/hw/android.hardware.sample@1.0-impl.so
/vendor/lib/hw/android.hardware.sample@1.0-impl.so
/system/lib64/android.hardware.sample@1.0.so
/system/lib/android.hardware.sample@1.0.so

二、构建binder service

1.现在有了库,我们还需要构建binder通信服务.

文件名:hardware/interfaces/sample/1.0/default/android.hardware.sample@1.0-service.rc
代码
service sample_service /vendor/bin/hw/android.hardware.sample@1.0-serviceclass haluser systemgroup systemseclabel u:r:init:s0   //我的android9.0的环境关闭了selinux所以加上这行

2.设定sample_service服务.接下来完善服务代码:

文件路径:android/hardware/interfaces/sample/1.0/default/service.cpp
代码:
#define LOG_TAG "android.hardware.sample@1.0-service"#include <android/hardware/sample/1.0/ISample.h>
#include <hidl/LegacySupport.h> //need log libusing android::hardware::sample::V1_0::ISample;
using android::hardware::defaultPassthroughServiceImplementation;int main()
{return defaultPassthroughServiceImplementation<ISample>();
}

3.在Android.bp中添加对服务器的编译:

文件路径:android/hardware/interfaces/sample/1.0/default/Android.bp
在文件最后面加上以下代码
cc_binary {name: "android.hardware.sample@1.0-service",defaults: ["hidl_defaults"],proprietary: true,relative_install_path: "hw",srcs: ["service.cpp"],init_rc: ["android.hardware.sample@1.0-service.rc"],shared_libs: ["libhidlbase","libhidltransport","libhardware","libutils","liblog","android.hardware.sample@1.0",],
}

4.android/hardware/interfaces/sample/1.0/default/如下

为了让服务器被客户端访问到,还需要在device/autochips/ac8257_demo/manifest.xml(不同厂商路径不同)添加如下:

      <hal format="hidl"><name>android.hardware.sample</name><transport>hwbinder</transport><version>1.0</version><interface><name>ISample</name><instance>default</instance></interface></hal>

5.mmm编译生成库文件和service文件

 mmm hardware/interfaces/sample/1.0/default/ 生成库文件和service文件
/vendor/lib64/hw/android.hardware.sample@1.0-impl.so
/vendor/lib/hw/android.hardware.sample@1.0-impl.so
/system/lib64/android.hardware.sample@1.0.so
/system/lib/android.hardware.sample@1.0.so
/vendor/etc/init/android.hardware.sample@1.0-service.rc (在out目录删除文件,项目全编的时候不会生成)
/vendor/bin/hw/android.hardware.sample@1.0-service(在out目录删除文件,项目全编的时候不会生成)

6.修改build/make/target/product/vndk/28.txt和 build/make/target/product/vndk/current.txt

添加如下,记得按照字母排列顺序位置添加

+VNDK-core: android.hardware.sample@1.0.so

三、添加测试程序

/hardware/interfaces/sample/client/helloworld.cpp

文件路径:/hardware/interfaces/sample/client/helloworld.cpp
代码:
#include <android/hardware/sample/1.0/ISample.h>
#include <hidl/Status.h>
#include <hidl/LegacySupport.h>
#include <utils/misc.h>
#include <hidl/HidlSupport.h>
#include <stdio.h>using android::hardware::sample::V1_0::ISample;
using android::sp;
using android::hardware::hidl_string;int main()
{android::sp<ISample> service = ISample::getService();if(service == nullptr){printf("xingchen Failed to get service\n");return -1;}printf("xingchen succeed to get service\n");service->init();return 0;}

/hardware/interfaces/sample/client/Android.mk

文件路径:/hardware/interfaces/sample/client/Android.mk
代码:
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE := helloworld
LOCAL_SRC_FILES := helloworld.cpp
LOCAL_SHARED_LIBRARIES := \liblog \libhidlbase \libutils \android.hardware.sample@1.0 \include $(BUILD_EXECUTABLE)

四、把上面的service,rc和client端的可执行文件helloworld打包进固件.

/device/autochips/ac8257/device.mk文件中加入代码PRODUCT_PACKAGES += helloworld
PRODUCT_PACKAGES += \android.hardware.sample@1.0-impl \android.hardware.sample@1.0-service

五、全编整个工程并烧入机器。

在全编之前可以把out目录下的上面mmm出来的文件删除,确保全编的时候相关文件可以一起编译出来。

cd out/target/product/ac8257_demo/
find ./system -name "*android.hardware.sample*" | xargs rm -rf
find ./vendor -name "*android.hardware.sample*" | xargs rm -rf
/vendor/lib64/hw/android.hardware.sample@1.0-impl.so
/vendor/lib/hw/android.hardware.sample@1.0-impl.so
/system/lib64/android.hardware.sample@1.0.so
/system/lib/android.hardware.sample@1.0.so
/vendor/etc/init/android.hardware.sample@1.0-service.rc
/vendor/bin/hw/android.hardware.sample@1.0-service (服务端)
/vendor/bin/helloworld   (客户端)

六、启动机器 ps - A  | grep android.hardware.sample@1.0-service 发现server已经起来了

logcat -s xingchen &   然后执行客户端helloworld

客户端已经成功调用服务器的接口.

七、遇到的问题

1.  在调试的时候手动执行/vendor/bin/hw/android.hardware.sample@1.0-service出现

CANNOT LINK EXECTABLE ...... :library ......;错误

原因是在hardware/interfaces/sample/1.0/default/Android.bp中加入了"android.hardware.sample@1.0-impl"导致的,删除即可。

cc_binary {name: "android.hardware.sample@1.0-service",defaults: ["hidl_defaults"],proprietary: true,relative_install_path: "hw",srcs: ["service.cpp"],init_rc: ["android.hardware.sample@1.0-service.rc"],shared_libs: ["libhidlbase","libhidltransport","libhardware","libutils","liblog","android.hardware.sample@1.0","android.hardware.sample@1.0-impl", //加入这行导致,删除即可,网上参考,想不到这个地方是个坑],
}

android hidl简单实例1相关推荐

  1. Android JNI简单实例(android 调用C/C++代码)

    转载自 xiechengfa 最终编辑 xiechengfa Android JNI简单实例关键字: android.jni Android的jni实例 android 的应用程序(Dalvik VM ...

  2. Android Fragment 简单实例

    Android上的界面展示都是通过Activity实现的.Activity实在是太经常使用了.我相信大家都已经很熟悉了,这里就不再赘述. 可是Activity也有它的局限性,相同的界面在手机上显示可能 ...

  3. android 简单实现圆角,Android 实现圆角图片的简单实例

    Android 实现圆角图片的简单实例 实现效果图: 本来想在网上找个圆角的例子看一看,不尽人意啊,基本都是官方的Demo的那张原理图,稍后会贴出.于是自己自定义了个View,实现图片的圆角以及圆形效 ...

  4. android 自定义 滑动删除,Android_Android ListView实现仿iPhone实现左滑删除按钮的简单实例,需要自定义ListView。这里就交Fl - phpStudy...

    Android ListView实现仿iPhone实现左滑删除按钮的简单实例 需要自定义ListView.这里就交FloatDelListView吧. 复写onTouchEvent方法.如下: @Ov ...

  5. Android调用高德地图直接导航的简单实例

    在学校最近做了一个小APP,脑子笨怕忘,写个博客记录一下. 简单来说就是保存地点,然后单击直接打开高德地图APP并从当前所在地导航到保存的地点.因为是小型学习用的,所以保存地点采用了Android本地 ...

  6. 安卓Android ViewModel 超简单实例

    安卓Android ViewModel 超简单实例 文章目录 安卓Android ViewModel 超简单实例 前言 使用步骤 1.引入库 2.继承ViewModel 并定义一个对象 3.到处去用 ...

  7. android怎么判断当前网络是否可用,Android 判断当前网络是否可用简单实例

    Android 判断当前网络是否可用简单实例 用户手机当前网络可用:WIFI.2G/3G网络,用户打开与不打开网络,和是否可以用是两码事.可以使用指的是:用户打开网络了并且可以连上互联网进行上网. 首 ...

  8. android js变量定义数组长度,js 声明数组和向数组中添加对象变量的简单实例

    数组有四种定义的方式 使用构造函数: var a = new Array(); var b = new Array(10); var c = new Array("first", ...

  9. Android 驱动(8)---简单实例讲解linux的module模块编译步骤

    简单实例讲解linux的module模块编译步骤 原博文地址http://blog.sina.com.cn/s/blog_4ba5b45e0102v25h.html ----------------- ...

  10. android java调用c_Android JNI简单实例(android 调用C/C++代码)

    Android的jni实例 android 的应用程序(Dalvik VM)中使用JNI(Java Native Interface)调用C/C++开发的共享库. c/c++中调用java程序的方法以 ...

最新文章

  1. 动画学院动漫节,周末预定!
  2. Express 工具库中的 Application 对象
  3. 【蔡勒公式 】根据给定的年月日求出对应星期几
  4. 体验 PHP under .NET Core
  5. net framework 3.5 安装错误_PageAdmin CMS建站系统报http403错误的解决方案
  6. mysql where true_在MySQL中选择查询,检查字符串或在where子句中检查是否为true?
  7. cmd 环境下载文件的几种方法
  8. 天馈系统驻波比概念,产生的原因,问题现象
  9. [USACO题库]1.2.3 Name That Number命名那个数字
  10. 物理 常见力与牛顿三定律
  11. 解决Windows10下java环境变量配置不生效的问题
  12. MATLAB 解数独
  13. 《Python语言程序设计基础》嵩天著-第3章程序部分练习题答案
  14. Vue前端报错及原因分析集合
  15. 企业微信为何出现信息发不出去的情况
  16. 麦克风阵列声音定位简介【转】
  17. 关于浏览器主页被劫持问题解决办法
  18. 【Quicker】您的指尖工具箱
  19. android飞机大战
  20. unity 2D动画不补帧

热门文章

  1. RTX3070深度学习环境配置
  2. GIS应用技巧之联合
  3. 使用字体编辑软件修改字体
  4. 泰坦尼克号幸存预测项目
  5. Linux压缩、解压、打包文件 修改文件所属组
  6. 全国计算机三级网络技术感悟,这几天准备计算机三级考试的感悟
  7. Smplayer命令行模式下的用法
  8. 云计算技术基础【12】
  9. oracle中both,ORACLE:scope=both|memery|spfile
  10. 小狮子荣光不复 瑞星信息去年亏损7300万元