鸿蒙手机版JNI实战(JNI开发、SO库生成、SO库使用)

鸿蒙JNI开发现状

现阶段,不只鸿蒙JNI相关的开发资料较少,并且Phone相关的JNI开发资料几乎没有,这对于新入行的鸿蒙开发者们来讲,很是不友好。html

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

案例演示

废话很少说了,接下来,咱们来演示鸿蒙手机版工程是如何作JNI开发的。c++

案例1:Native项目

若是开发者们只是想作简单的Native开发,并不是为第三方提供SO库,这就很是简单了,详细以下:json

一、建立Native C++工程

目前,经过DevEco-Studio建立建立Native C++模板类型的工程时,只有Car支持这种模板(Phone默认不包含Native C++模板)。
没必要担忧,咱们就先建立Car类型的工程,而后选择Native C++模板,以下图:app

而后,输入工程名称等信息,以下图:工具

接下来,选择C++标准库,默认就能够了,以下图:测试

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

二、修改DeviceType配置

当前工程默认是Car类型的,想要支持手机,咱们只须要修改DeviceType便可。ui

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

将“car”改成“phone”,便可支持运行在手机设置上了(是否是超级简单呢),以下图:

三、测试

我这边使用的是鸿蒙手机进行测试的(鸿蒙手机是:由安卓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的形式来开发了,一样也不怎么复杂。

一、问题分析

如今有一个问题:建立module时,连native c++模板都没有了,以下图:

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

解决方案:

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

二、建立Car类型的Native C++模板工程

比较简单,你们能够参考案例1的工程建立流程(此处就再也不重复截图了)

三、建立Harmony os Library Module

你们直接下一步就好(此处就再也不截图了)。

四、修改entry deviceType类型(改为phone)

五、拷贝文件

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

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

六、新建类定义native方法

为了加深你们理解,此处再也不使用默认的hello.cpp了,我们实现一个简单的JNI开发:
新建TestNative类,定义native方法,以下图:

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

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

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

七、修改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)
八、生成so库

此时,咱们libnative module库的功能已经实现了,能够生成so库给其余工程使用了。

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

entry依赖libnative,咱们能够在entry的build.gradle中进行配置:

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

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

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

一、定义的native方法的Java类:提供libnative的har包便可(给第三方时,通常不提供源码)
二、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基础的相关文章:
http://www.javashuo.com/article/p-hvwycntp-cb.html
http://www.javashuo.com/article/p-ypcjrqqg-bs.html

视频讲解:
https://edu.csdn.net/course/detail/27043
https://edu.csdn.net/course/detail/27092

若是有问题,欢迎留言交流。 祝你们生活愉快、工做愉快,天天顺心、开心!!!

相关文章
相关标签/搜索