鴻蒙手機版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

若是有問題,歡迎留言交流。 祝你們生活愉快、工做愉快,天天順心、開心!!!

相關文章
相關標籤/搜索