突然看到一篇文章Android HIDL学习,跟这位大神是有一面之缘的,正好也想学习Android是怎么从 APP → JNI Client → HIDL

代码结构

代码我已经上传到了CSND的资源,首先我们看一下结构图和代码目录吧


1. Android 11/12中编译的源码 naruto目录
hareware/interface/naruto/
└── 1.0├── Android.bp├── default│   ├── Android.bp│   ├── android.hardware.naruto@1.0-service.rc│   ├── client.cpp│   ├── jni│   │   ├── Android.mk│   │   ├── CMakeLists.txt│   │   └── native-lib.cpp│   ├── Naruto.cpp│   ├── Naruto.h│   └── service.cpp└── INaruto.hal2. Android 11/12源码编译的产物 out目录
system/lib64/android.hardware.naruto@1.0.so
system/lib64/libnative-lib.so
system/app/app-debug.apkvendor/lib64/hw/android.hardware.naruto@1.0-impl.so
vendor/bin/hw/android.hardware.naruto@1.0-service
vendor/bin/hw/naruto_client
vendor/etc/init/android.hardware.naruto@1.0-service.rc3. Android Studio中编译的 MyApplication目录
这个就不赘述了,常规代码,逻辑也不多,但有naruto和sasiki的个人壁纸,还挺帅的

HIDL接口

按着开头提到的博客,常规的创建hidl文件的方法,这里也可以不用make hidl-gen,使用out目录中已经生成的一样可以用

PACKAGE=android.hardware.naruto@1.0
LOC=hardware/interfaces/naruto/1.0/default/
make hidl-gen -j64
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./hardware/interfaces/update-makefiles.sh

这里要注意大神博客上提到INaruto.hal的位置可以随便放,但实际上是不可以的,必须按结构目录来放置,不然无法使用hidl-gen生成c++ impl的文件,还有我使用hidl-gen生成的文件域不对,对着用了好几遍都有问题,这里我手动改的,不然编译的时候找不到INaruto这个类

- namespace android::hardware::naruto::implementation
+ namespace android::hardware::naruto::V1_0::implementation

添加完hidl后别忘了在manifest.xml去添加实现的接口。编译完成后,将我们生成的so和bin都adb push到对应的目录,手动运行service,再运行natruo_client我们写的getservice的测试代码,输出结果如下,那hidl这一块我们就算实现了,再次感谢这个大神

manifest.xml
<hal format="hidl"><name>android.hardware.naruto</name><transport>hwbinder</transport><version>1.0</version><interface><name>INaruto</name><instance>default</instance></interface>
</hal>run result
Hello World, JayZhang

APP 应用

app的话,我之前也没接触过,Android Studio的安装教程网上搜搜一大堆,写APP我推荐看这个博主手把手教你用Android Studio写一个APP,对我来说真的很有帮助,能在短时间内速成一个APP,当然写APP的过程中也让我了解了一些App的知识,比如

(1)起始函数不是main而是onCreate
(2)activity_main.xml是用来对当前页面布局的
(3)MainActivity.java是用来实现activity_main.xml这个页面上的控制
(4)页面按钮点击触发事件常用onClick

我们这个APP主要有两个页面,实现的功能为鸣人和佐助的爱恨情仇(当佐助喊鸣人的名字后,鸣人也能回应佐助名字)
(1)主页面MainActivity上有一个按钮为Naruto,按下后触发调转页面,
(2)调转页面FunctionActivity上有一个text用来显示从JNI获取的string字符串Sasiki

JNI Native

首先我现在AndroidStudio中实现JNI来测试好功能,AndroidStduio网上说是可以使用NDK进行编译,但感觉没有CMake方便,我这边就是通过CMakeList.txt来进行编译libnative-lib.so,实现的很简单就是返回一个string,这个按固定格式去添加即可,前面就是java\com\example\myapplication + FunctionActivety.java调用jni的文件 + 调用的函数接口

native-lib.cpp  测试naruto_client
#include <string>
#include <jni.h>extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_FunctionActivity_getStringFromJni(JNIEnv* env,jobject /*this */){std::string hello = "SASIKI";return env->NewStringUTF(hello.c_str());
}app调转页面中的实现
public class FunctionActivity extends AppCompatActivity {private TextView myTextView;static {System.loadLibrary("native-lib");}public native String getStringFromJni();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_function);myTextView = findViewById(R.id.function);myTextView.setText(getStringFromJni());}}
后续我们有在这native-lib.cpp中添加了getservice的操作
#include <string>
#include <jni.h>
#include <android/hardware/naruto/1.0/INaruto.h>
#include <hidl/Status.h>
#include <hidl/LegacySupport.h>
#include <utils/misc.h>
#include <hidl/HidlSupport.h>
#include <stdio.h>using android::hardware::naruto::V1_0::INaruto;
using android::sp;
using android::hardware::hidl_string;extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_FunctionActivity_getStringFromJni(JNIEnv* env,jobject /*this */){std::string hello = "SASIKI";std::string hello2 = "Orochimaru";android::sp<INaruto> service = INaruto::getService();if(service == nullptr) {printf("Failed to get service\n");return env->NewStringUTF(hello2.c_str());}service->helloWorld("JayZhang", [&](hidl_string result) {printf("%s\n", result.c_str());});return env->NewStringUTF(hello.c_str());}

运行结果

关闭sepolicy,运行的时候,APP报错的carsh如下:

dlopen failed: library "/system/lib64/libnative-lib.so" needed or dlopened by "/apex/com.android.art/lib64/libnativeloader.so"is not accessible for the namespace "classloader-namespace"

网上搜了一大堆,都是一样的回复,让你去修改/system/etc/public.libraries.txt,将需要的libnative-lib.so去添加到这个文件中,实际操作中发现修改后会导致开不了机,报错就是因为添加的so的原因;后来还尝试过将所有的依赖库都防止到data/app中lib目录中,最终也能运行起来,但在data目录中是无法实现从vendor获取service的功能
    然后看了这个博客才恍然大悟Android系统编译apk dlopen so失败,public.libraries.txt这个方法在Android 9.0的时候其实就失效了,然后我意识到我从Android Stduio去lanuch的这个测试app,其安装是在data/app目录下,这其实上就是一个三方app,而不是system app,按Android现在的策略三方APP就是无法访问Systemlib的,其实我们只要将我们的apk push到system/lib下即可,当时花了我好久的时间才认识到这个问题,最终apk在手机上运行的结果就是如下画面

Android JNI HIDL 简单实例学习相关推荐

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

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

  2. Android JNI开发入门之一

    JNI在Android系统中有着广泛的应用.Android系统底层都是C/C++实现的,上层提供的API都是Java的,Java通过JNI调用底 层的实现.比如:Android API多媒体接口Med ...

  3. java jni 数据类型_【Android JNI】Native层解析Java复杂数据类型HashMap

    前提 Java HashMap 是基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.HashMap是存放引用类型数据的容器,只能存放引用数据类型,不能存 ...

  4. Android JNI 和 NDK

    1.Android NDK 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...

  5. android jni malloc和free的使用

    今天,简单讲讲android在jni如何使用malloc和free进行内存的分配和释放. 这个其实也是C++相关的知识,不过jni需要用到,所以这里记录一下. 一.malloc()和free()的基本 ...

  6. android jni new/delete 和 new[]/delete[]

    今天,简单讲讲android里再jni使用new时如何释放内存. 这个其实是和C++有关的知识,不过jni编程时还是需要注意的.所以这里记录一下. new 和 delete 到底是什么? 如果找工作的 ...

  7. android jni jstring 转 char*

    今天,简单讲讲Android jni如何将java的Sring转成char*. 这个之前一直不理解,所以我都是android传入byte[]转成char*,有一篇博客专门讲了这个.后来发现用Strin ...

  8. android jni 释放资源

    今天,简单讲讲android 如何释放在jni新建得 结构体等资源. 因为android里是自动释放资源的,所以之前没有注意这一点,后来查找资料才发现jni需要自己释放资源.这里记录一下. JNI 编 ...

  9. android jni 返回java类

    今天,简单讲讲android 在jni中如何返回一个java的类. 之前,我写了一些关于jni的博客,里面返回的都是简单的int类型,那么如果我需要返回很多int和String类型,那么怎么办呢?当然 ...

  10. android jni 将BYTE* 和 jbyteArray 之间的转换

     今天,简单讲讲如何在jni中将  BYTE* 转成 jbyteArray. 这个是我在做jni时碰到的问题.因为c传回的值是BYTE*,而返回给java代码是byte[],对应的jni的数据 ...

最新文章

  1. [operator]ubuntu + git
  2. [整理]Git使用文章整理
  3. java aspose重叠_Aspose.Words - 在特定位置合并两个文档
  4. 华为java 优招面试题_2017华为优招笔试题
  5. 微服务权限控制(二)共享Session方式的登录认证
  6. 本科化学 研究生力学 毕业从事销售最后却转行算法
  7. Adobe 全家桶关闭自动更新?技巧来啦!
  8. PTV-VISSIM交通仿真
  9. Python爬虫方法三部曲
  10. 微信php开发实例,微信小程序php后端开发实例
  11. Android Studio 开发APP流程
  12. 【四足机器人--支撑相足端反作用力预测】(5)ConvexMPCLocomotion代码解析
  13. Java实现杨辉三角形
  14. cousera“Neural NetWorks and Deep learning读书笔记
  15. ink 合约篇(一)| 部署 ink 合约
  16. mac获取ios应用包名
  17. 斜度线在CAD中你是怎么画的?
  18. echarts画出特殊形状的柱状图
  19. 李开复:点子太多的聪明人不适合创业
  20. 虚拟现实是计算机软件么,虚拟现实技术对于电脑软件、硬件的配置要求有哪些?...

热门文章

  1. 单片机定时器TMOD与TCON
  2. G312高速公路S标段路线设计--金陵科技学院道路毕业设计
  3. 树莓派安装Gqrx软件(Linux下SDR 软件无线电接收软件之一)
  4. 最新弱口令字典,常用密码,弱密码集合
  5. css城市列表,js 获取全国城市列表方法
  6. 《虚幻4引擎快速入门》视频教程
  7. NGINX转发udp、tcp
  8. linux udp转发脚本,使用Socat转发TCP和UDP流量搭建跳板教程及一键脚本
  9. 计算机核心期刊排名及投稿信息
  10. oracle的dbv命令,DBV(DBVERIFY)工具