鸿蒙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. The last packet successfully received from the server was 49,061,696 millise

    解决连接:https://blog.csdn.net/pandajava/article/details/41946251

  2. Flannel和Calico网络插件工作流程对比

    Flannel和Calico网络插件对比   Calico简介 Calico是一个纯三层的网络插件,calico的bgp模式类似于flannel的host-gw Calico方便集成 OpenStac ...

  3. 第28天学习打卡(Date和Calendar类 基本类型的包装类 集合 增强for循环 )

    Date和Calendar类 简介 日期和日历类,用于操作日期相关信息. 构造方法 Date(): 构造一个日期对象,当前系统时间,精确到毫秒. Date(long): 构造一个日期对象,时间为自&q ...

  4. Docker搭建Hadoop环境

    文章目录 Docker搭建Hadoop环境 Docker的安装与使用 拉取镜像 克隆配置脚本 创建网桥 执行脚本 Docker命令补充 更换镜像源 安装vim 启动Hadoop 测试Word Coun ...

  5. 【转载】快速理解android View的测量onMeasure()与MeasureSpec

    笔者之前有一篇文章已经使用onMeasure()解决了listview与scollview的显示冲突问题,博客地址如下: onMeasure简单方法 完美解决ListView与ScollView冲突问 ...

  6. 源码解析之 Mybatis 对 Integer 参数做了什么手脚?

    title: 源码解析之 Mybatis 对 Integer 参数做了什么手脚? date: 2021-03-11 updated: 2021-03-11 categories: Mybatis 源码 ...

  7. Mysql在windows环境如何修改密码?

    1.关闭正在运行的MySQL服务. 2. 打开DOS窗口,转到mysql\bin目录. 3. 输入mysqld --skip-grant-tables 回车.--skip-grant-tables 的 ...

  8. flutter简易教程

    跟Java等很多语言不同的是,Dart没有public protected private等关键字,如果某个变量以下划线 _ 开头,代表这个变量在库中是私有的.Dart中变量可以以字母或下划线开头,后 ...

  9. java IO流文件拷贝文件(字节流标准写法)

    public static void copyFile(String srcPath, String destPath) { FileInputStream fis = null; FileOutpu ...

  10. python-类的多态的理解

    了解多态 多态指的是一类事物有多种形态 .定义:多态是一中使用对象的方式,更容易编写出通用的代码,做出通用的编程,一适应需求的不断变化 实现步骤: 1.定义父类,并提供公共方法 2.定义子类,并重写父 ...