Android NDK Gradle3.0 以上最新生成.so之旅

寫這篇文章前,自己踩過很多坑,希望能助大家一步跨坑。
1、環境搭建:通過SDKManager-SDK Tools下載NDK插件,下載後到SDK Location裏面檢查裏面的NDK路徑:
這裏寫圖片描述

檢查local.properties文件裏面有沒有NDK路徑:
這裏寫圖片描述

2、使用native關鍵字編寫JNI接口:
這裏寫圖片描述

編寫之後,make project,再到工程目錄E:\work\MyApplication\stujni\build\intermediates\classes\debug\com\huazi\stujni\jni中看到自己編譯後的class文件JNIUtils.class如下圖所示:
這裏寫圖片描述

3、使用javah生成.h頭文件 步驟如下:
1.打開Terminal,然後在命令行中先進入到工程的main目錄下 cd app/src/main。
2.輸入命令:javah -d jni -classpath (剛纔生成class文件的絕對路徑)
例如:javah -d jni -classpath E:\work\MyApplication\stujni\build\intermediates\classes\debug com.huazi.stujni.jni.JNIUtils(注意debug後的空格)
這裏寫圖片描述

這個文件.h文件不需要做任何修改,默認即可。
現在我們來寫一個test的C文件TestSerial.c同.h文件一樣放到jni文件夾下
然後在TestSerial.c文件裏面引入生成.h文件:
這裏寫圖片描述

到這裏我們的方法就實現完畢了 直接調用看結果:
這裏寫圖片描述

最重要的生成.so文件:
gradle3.0以前生成方式:
在根目錄gradle.properties下面加上:
android.useDeprecatedNdk=true意思就是允許使用低版本的NDK
在module下面的build.gradle下面加上ndk節點如下圖:
ndk {
moduleName “serial_port”//定義自己Ndklibrary的名字
ldLibs “log” //添加log庫
// 設置支持的SO庫架構
abiFilters ‘armeabi’
}
需要這兩步就可以運行生成so文件了,然兒,並沒有想象的那麼順利,報錯了,我頓時心中飛過一萬隻草泥瑪,上log:
Error:Execution failed for task ‘:app:compileDebugNdk’.

Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio. Please switch to a supported build system.
Consider using CMake or ndk-build integration. For more information, go to:
https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile
To get started, you can use the sample ndk-build script the Android
plugin generated for you at:
/Users/apple/Desktop/AndroidJNITest/app/build/intermediates/ndk/debug/Android.mk
Alternatively, you can use the experimental plugin:
https://developer.android.com/r/tools/experimental-plugin.html
To continue using the deprecated NDK compile for another 60 days, set
android.deprecatedNdkCompileLease=1512283120054 in gradle.properties

百思不得其解,我之前一直是這樣搞的呀,爲什麼現在不行了呢。
遇到錯誤不要慌張,程序員就是不怕事。

仔細看了下log,大概意思說:
android.useDeprecatedNdk不再支持了
讓使用CMake or ndk-build
然後還有鏈接
考慮使用CMake或ndk構建集成。要了解更多信息,請訪問:
https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile
首先,您可以使用Android的ndk構建腳本示例插件爲您生成:
/Users/apple/Desktop/AndroidJNITest/app/build/intermediates/ndk/debug/Android.mk
或者,你可以使用實驗插件:
https://developer.android.com/r/tools/experimental-plugin.html
繼續使用已棄用的NDK編譯60天,設置
在gradle.properties
android.deprecatedNdkCompileLease = 1512283120054(這個測試不起作用)
經過各種查資料,發現原來在gradle3.0以上以前這種方法不在支持
學習過程就不詳細描述了,直接上結果:
先通過SDKManager下載:CMake和LLDB
這裏寫圖片描述
在build.gradle的defaultConfig節點下加入:
// 使用Cmake工具
externalNativeBuild {
cmake {
cppFlags “serial_port”
//生成多個版本的so文件
abiFilters ‘arm64-v8a’, ‘armeabi-v7a’
}
}
在build.gradle的android節點下加入:
// 配置CMakeLists.txt路徑
externalNativeBuild {
cmake {
path “CMakeLists.txt” //編譯後so文件的名字
}
}
這裏寫圖片描述
添加CMakeLists.txt文件到build.gradle文件同級目錄下,具體內容如下:
# For more information about using CMake with Android Studio, read the

documentation: https://d.android.com/studio/projects/add-native-code.html

Sets the minimum version of CMake required to build the native library.

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

Creates and names a library, sets it as either STATIC

or SHARED, and provides the relative paths to its source code.

You can define multiple libraries, and CMake builds them for you.

Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
# 設置so文件名稱.
serial_port
# Sets the library as a shared library.
SHARED
# 設置這個so文件爲共享.
# Provides a relative path to your source file(s).
# 設置這個so文件爲共享.
src/main/jni/TestSerial.c)

Searches for a specified prebuilt library and stores the path as a

variable. Because CMake includes system libraries in the search path by

default, you only need to specify the name of the public NDK library

you want to add. CMake verifies that the library exists before

completing its build.

find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )

Specifies libraries CMake should link to your target library. You

can link multiple libraries, such as libraries you define in this

build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
# 制定目標庫.
serial_port
# Links the target library to the log library
# included in the NDK.
${log-lib} )
這裏寫圖片描述
所有流程都搞定,接下見證奇蹟:
這裏寫圖片描述

調用編譯過的.so庫
上邊編譯完成了,有人會問:我要的是編譯後的.so庫,別人用的時候直接拿來用就可以了,那該怎麼辦呢,直接把上面的so文件複製到相應的文件夾就ok了:
這裏寫圖片描述
到這裏,整個jni的調用過程就結束了,包括調用jni需要的環境以及調用的過程,最後.so文件的導出,都在上邊了,都是自己踩過的坑總結的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章