zoukankan      html  css  js  c++  java
  • 鸿蒙手机版JNI实战(JNI开发、SO库生成、SO库使用)

    鸿蒙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

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

    如果有问题,欢迎留言交流。
    祝大家生活愉快、工作愉快,每天顺心、开心!!!

  • 相关阅读:
    DOM节点删除之empty()和remove()的有参用法和无参用法
    DOM外部插入insertAfter()与insertBefore()
    DOM内部插入prepend()与prependTo()
    DOM外部插入after()与before()
    DOM内部插入append()与appendTo()
    jQuery节点创建与属性的处理 创建节点
    jQuery的属性与样式之元素的数据存储
    jQuery的属性与样式之样式操作.css()
    jQuery的属性与样式之切换样式.toggleClass()
    jQuery的属性与样式之增加样式.addClass()
  • 原文地址:https://www.cnblogs.com/qixingchao/p/14708857.html
Copyright © 2011-2022 走看看