Android JNI HIDL 简单实例学习
突然看到一篇文章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 简单实例学习相关推荐
- Android JNI简单实例(android 调用C/C++代码)
转载自 xiechengfa 最终编辑 xiechengfa Android JNI简单实例关键字: android.jni Android的jni实例 android 的应用程序(Dalvik VM ...
- Android JNI开发入门之一
JNI在Android系统中有着广泛的应用.Android系统底层都是C/C++实现的,上层提供的API都是Java的,Java通过JNI调用底 层的实现.比如:Android API多媒体接口Med ...
- java jni 数据类型_【Android JNI】Native层解析Java复杂数据类型HashMap
前提 Java HashMap 是基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.HashMap是存放引用类型数据的容器,只能存放引用数据类型,不能存 ...
- Android JNI 和 NDK
1.Android NDK 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...
- android jni malloc和free的使用
今天,简单讲讲android在jni如何使用malloc和free进行内存的分配和释放. 这个其实也是C++相关的知识,不过jni需要用到,所以这里记录一下. 一.malloc()和free()的基本 ...
- android jni new/delete 和 new[]/delete[]
今天,简单讲讲android里再jni使用new时如何释放内存. 这个其实是和C++有关的知识,不过jni编程时还是需要注意的.所以这里记录一下. new 和 delete 到底是什么? 如果找工作的 ...
- android jni jstring 转 char*
今天,简单讲讲Android jni如何将java的Sring转成char*. 这个之前一直不理解,所以我都是android传入byte[]转成char*,有一篇博客专门讲了这个.后来发现用Strin ...
- android jni 释放资源
今天,简单讲讲android 如何释放在jni新建得 结构体等资源. 因为android里是自动释放资源的,所以之前没有注意这一点,后来查找资料才发现jni需要自己释放资源.这里记录一下. JNI 编 ...
- android jni 返回java类
今天,简单讲讲android 在jni中如何返回一个java的类. 之前,我写了一些关于jni的博客,里面返回的都是简单的int类型,那么如果我需要返回很多int和String类型,那么怎么办呢?当然 ...
- android jni 将BYTE* 和 jbyteArray 之间的转换
今天,简单讲讲如何在jni中将 BYTE* 转成 jbyteArray. 这个是我在做jni时碰到的问题.因为c传回的值是BYTE*,而返回给java代码是byte[],对应的jni的数据 ...
最新文章
- [operator]ubuntu + git
- [整理]Git使用文章整理
- java aspose重叠_Aspose.Words - 在特定位置合并两个文档
- 华为java 优招面试题_2017华为优招笔试题
- 微服务权限控制(二)共享Session方式的登录认证
- 本科化学 研究生力学 毕业从事销售最后却转行算法
- Adobe 全家桶关闭自动更新?技巧来啦!
- PTV-VISSIM交通仿真
- Python爬虫方法三部曲
- 微信php开发实例,微信小程序php后端开发实例
- Android Studio 开发APP流程
- 【四足机器人--支撑相足端反作用力预测】(5)ConvexMPCLocomotion代码解析
- Java实现杨辉三角形
- cousera“Neural NetWorks and Deep learning读书笔记
- ink 合约篇(一)| 部署 ink 合约
- mac获取ios应用包名
- 斜度线在CAD中你是怎么画的?
- echarts画出特殊形状的柱状图
- 李开复:点子太多的聪明人不适合创业
- 虚拟现实是计算机软件么,虚拟现实技术对于电脑软件、硬件的配置要求有哪些?...