鸿蒙JNI开发现状

现阶段,不仅鸿蒙JNI相关的开发资料较少,而且Phone相关的JNI开发资料几乎没有,这对于新入行的鸿蒙开发者们来说,非常不友好。

也可能会给Android工程(使用了SO库的工程)在迁移至鸿蒙系统时造成了阻碍。

案例演示

废话不多说了,接下来,我们来演示鸿蒙手机版工程是如何做JNI开发的。

案例1:Native项目

如果开发者们只是想做简单的Native开发,并非为第三方提供SO库,这就非常简单了,详细如下:

1、创建Native C++工程

目前,通过DevEco-Studio创建创建Native C++模板类型的工程时,只有Car支持这种模板(Phone默认不包含Native C++模板)。

不必担心,我们就先创建Car类型的工程,然后选择Native C++模板,如下图:

然后,输入工程名称等信息,如下图:

接下来,选择C++标准库,默认就可以了,如下图:

点击【Finish】,工程就创建好了。

2、修改DeviceType配置

当前工程默认是Car类型的,想要支持手机,我们只需要修改DeviceType即可。

首先,找到config.json文件,如下图:

将“car”改为“phone”,即可支持运行在手机设置上了(是不是超级简单呢),如下图:

3、测试

我这边使用的是鸿蒙手机进行测试的(鸿蒙手机是:由安卓P40升级的Harmony OS)。

另外,在真机上调试、运行工程,需要申请证书(我这边已申请,没有的同学,可以去华为官网申请)。

测试前,我们先看下默认的模板工程结构:

整体的调用流程也很简单:

开发者运行工程 --> build工程 --> 执行build.gradle
--> 执行里面的externalNativeBuild --> 生成so库文件 --> app启动
--> 页面加载 --> 调用MainAbilitySlice类 --> 查找并加载so库
--> 在onStart生命周期方法中调用native方法 --> 执行so中的native实现方法
--> 返回结果 --> 绑定给text控件(最终将结果显示在页面上)

手机上的运行结果(直接横屏显示......这是因为我们的工程本身是Car类型的模板工程,UI样式默认设置的是横屏的。如果不喜欢,开发者们也可以自行修改UI样式):

so库创建的默认位置:

案例2:Native项目

如果开发者们不仅要做native开发,还希望将so文件提供给第三方使用,这样我们就需要以module的形式来开发了,同样也不怎么复杂。

1、问题分析

现在有一个问题:创建module时,连native c++模板都没有了,如下图:

这不是要让广大开发者们生气、抓狂、准备画圈圈了么。

解决方案:

其实,我们还有其他的方式(原因:JNI开发也就涉及到native方法定义、native源码、Cmake配置文件、Gradle配置等内容):我们可以新建一个Car类型的Native C++工程和一个Harmony os Library Module,然后将模板工程entry中的JNI代码迁移到Harmony os Library Module中。

2、创建Car类型的Native C++模板工程

比较简单,大家可以参考案例1的工程创建流程(此处就不再重复截图了)

3、创建Harmony os Library Module

大家直接下一步就好(此处就不再截图了)。

4、修改entry deviceType类型(改成phone)

5、拷贝文件

将entry下的.cxx目录和cpp目录拖拽到 libnative module中的相同位置:

将entry下的build.gradle中 native 编译脚本拷贝至 libnative module中相同位置:

6、新建类定义native方法

为了加深大家理解,此处不再使用默认的hello.cpp了,咱们实现一个简单的JNI开发:

新建TestNative类,定义native方法,如下图:

通过DevEco-Studio的命令工具Terminal,进入java目录,创建头文件:

执行命令:
进入module目录: cd libnative/src/main/java/
根据native方法生成头文件:javah -jni xxxx(包名).类名

将头文件拷贝到cpp目录下,然后,右键cpp目录,创建头文件对应的实现类:

7、修改CmakeList.txt
# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(TestNative) add_library(native SHARED testnative.cpp)
target_link_libraries(native)
8、生成so库

此时,我们libnative module库的功能已经实现了,可以生成so库给其他工程使用了。

我们需要先让libnative被entry依赖,这样运行app时,才会自动加载libnative,从而执行其build.gradle中的native build配置,生成so库。

entry依赖libnative,我们可以在entry的build.gradle中进行配置:

运行app后,查看libnative module下,生成了so库:

9、生成的so库,怎么提供给其他工程使用呢?

也很简单,JNI主要包含了两部分内容:定义的native方法的Java类(Java代码中调用so库的入口)、native方法的实现类,我们只需要将这两部分提供给他们就可以了:

1、定义的native方法的Java类:提供libnative的har包即可(给第三方时,一般不提供源码)
2、native方法的实现类:提供so库文件即可

测试:

我们简单点,直接把so库、har提供给我们工程的entry进行测试即可,不再新建工程了(因为,我比较懒,哈哈):

首先,我们先取消entry build.gradle中依赖libnative的配置(防止重复依赖,因为:har已包含了libnative的Java代码):

我们将libnative中的so库、har拷贝到entry的libs目录下:

在页面中编写调用har中native方法的代码:

运行app(运行前最好clean下工程、同步下gradle,确保依赖的是改har,而非工程中的libnative module):

总结

鸿蒙进行JNI开发其实不难,与安卓基本上一致,只是参考资料少一些而已。

如果大家对JNI不熟悉,可以参考我之前写的JNI基础的相关文章:

https://www.cnblogs.com/qixingchao/p/11911764.html

https://www.cnblogs.com/qixingchao/p/11911787.html

如果有问题,欢迎留言交流。

祝大家生活愉快、工作愉快,每天顺心、开心!!!

鸿蒙手机版JNI实战(JNI开发、SO库生成、SO库使用)的更多相关文章

  1. java版gRPC实战之一:用proto生成代码

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  2. Android JNI学习(二)——实战JNI之“hello world”

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  3. JNI 实战全面解析

    项目决定移植一款C++开源项目到Android平台,开始对JNI深入研究. JNI是什么? JNI(JavaNative Interface)意为Java本地调用,它允许Java代码和其他语言写的代码 ...

  4. discuz手机版模板开发

    1.触屏版模板手机路径 discuz X3触屏版模板路径:/template/default/touch/forum/discuz.htm(主页面模板) discuz X3标准版模板路径:/templ ...

  5. ubuntu下整合eclipse和javah生成jni头文件开发android的native程序

    0:前言: 这两天一直在研究用android的jni调用第三方库,上网搜方法,但是都是泛泛而谈,没有demo,经过我几番折磨,写了n多的helloword工程,总是不成功,工程名字也就由helloow ...

  6. 手机版WEB开发经验分享,手机版网站开发注意事项,网站自适应,手机版网站自适应,移动安卓APP自适应

    转自 http://my.oschina.net/cart/blog/282477 做前端开发不短了,用过jQuery Mobile jqMobi 也纯手工写过.. 最后总结如下: jQuery Mo ...

  7. Android For JNI(一)——JNI的概念以及C语言开发工具dev-c++,编写你的第一个C语言程序,使用C启动JAVA程序

    Android For JNI(一)--JNI的概念以及C语言开发工具dev-c++,编写你的第一个C语言程序 当你的Android之旅一步步的深入的时候,你其实会发现,很多东西都必须去和framew ...

  8. JNI实战(三):JNI 数据类型映射

    在JNI实战(二):Java 调用 C 我们了解了JNI的静态注册和动态注册.也知道我们应该使用动态注册来进行JNI函数与Java方法之间的映射. 示例的映射表的数组为如下: static JNINa ...

  9. 红米手机4A怎么样刷入开发版获得ROOT权限

    小米的手机或平板不同手机型号一般情况官方都提供两个不同系统,可分为稳定版和开发版,稳定版没有提供root权限管理,开发版中就支持了root权限,在很多工作的时候我们需要使用的一些功能强大的app,都需 ...

随机推荐

  1. Error Code: 1366. Incorrect DECIMAL value: '0' for column '' at row -1 0.266 sec;

    Reference: https://stackoverflow.com/questions/35037288/incorrect-decimal-integer-value-mysql     Er ...

  2. 腾讯数据库tdsql部署与验证

    环境准备 | 主机 | IP | 配置(最低要求配置) | | :----- | ------------- | ------------------ | | node-1 | 192.168.1.8 ...

  3. ASP.NET Core重复读取Request.Body

    //HttpContext context.Request.EnableRewind(); //创建缓冲区存放Request.Body的内容,从而允许反复读取Request.Body的Stream u ...

  4. SpringMVC执行流程及源码分析

    SpringMVC流程及源码分析 前言 ​ 学了一遍SpringMVC以后,想着做一个总结,复习一下.复习写下面的总结的时候才发现,其实自己学的并不彻底.牢固.也没有学全,视频跟书本是要结合起来一起, ...

  5. Azure Front Door(一)为基于.net core 开发的Azure App Service 提供流量转发

    一,引言 之前我们讲解到使用 Azure Traffic Manager.Azure LoadBalancer.Azure Application Gateway,作为项目的负载均衡器来分发流量,转发 ...

  6. go中waitGroup源码解读

    waitGroup源码刨铣 前言 WaitGroup实现 noCopy state1 Add Wait 总结 参考 waitGroup源码刨铣 前言 学习下waitGroup的实现 本文是在go ve ...

  7. Learn Python the Hard Way,ex37-1

    本练习为复习python的符号和关键字 关键字有: #and or False True print(1==0 and 2==0, 1==0 or 2==0) print(False) print(T ...

  8. ApiTesting全链路接口自动化测试框架 - 新增数据库校验(二)

    在这之前我完成了对于接口上的自动化测试:ApiTesting全链路接口自动化测试框架 - 初版(一) 但是对于很多公司而言,数据库的数据校验也尤为重要,另外也有小伙伴给我反馈希望支持. 所以最近几天我 ...

  9. JavaCV 采集摄像头及桌面视频数据

    javacv 封装了javacpp-presets库很多native API,简化了开发,对java程序员来说比较友好. 之前使用JavaCV库都是使用ffmpeg native API开发,这种方式 ...

  10. MyBatis-Plus【踩坑记录01】

    不要使用Mybatis原生的SqlSessionFactory,而应使用MybatisSqlSessionFactory. 原因 依赖关系如下 因此会在使用Mybaits-Plus时默认的时Mybat ...