前言
這邊Android作為日常記錄,雖然破壞了文章隊形~ 最近人工智能挺火的,也稍微了解了一些庫,比如關於視覺庫openCV。要在安卓下調用這些C/C++庫,需要用到JNI開發,在此把過程分享一下。
概念
JNI:Java Native Interface的縮寫。提供了API供java和其他語言通信,主要是C/C++。
NDK:Native Development Kit,是 Android
的一個工具開發包 ,快速開發C
、 C++
的動態庫,並自動將so文件
和應用一起打包成 APK。
JNI和NDK關系:在Android中通過NDK,使用JNI與本地Java代碼交互。
分析
分析要做的事情
1、配置NDK環境。(這里用的安卓開發工具是Android studio,as的配置就不細說了)
2、編寫C/Cpp文件。
3、編譯生成so文件供原生安卓調用。
4、編寫本地native方法。
配置NDK環境
方式一:在線配置
- 打開sdk manager
- 點擊sdk tools
- 勾選CMake、LLDB、NDK,點擊install。
慢慢等吧......順利的話下載完點擊APPLY--->OK,那么恭喜。如果提示下載失敗,很大可能是沒掌握科學上網=。=!!,此時可以試試方式二。
方式二:離線安裝
- 下載NDK離線安裝包並解壓,修改文件夾名字為ndk-bundle,放在你安裝Android studio的sdk目錄下,重啟android studio就可以了。(推薦下載地址AndroidDevTools.com,資源較為干凈放心)
- 不想放在sdk目錄下的可以解壓到任何一個盤,點擊android studio --> file --> project structure --> SDK location --> Android NDK Location設置ndk目錄,重啟android studio。
關聯NDK與項目:
1、gradle --> local.properties -->添加配置 ndk.dir=/Users/susan/Android/sdk/ndk-bundle。 (一般情況下這句是自動加上的,假如你的ndk在sdk目錄下)
2、gradle --> gradle.propertiess -->添加配置 android.useDeprecatedNdk=true。 (一般情況下也是自動加的)
3、在gredle.build中添加ndk節點。
4、創建本地ImgFun.cpp文件,注意位置位於jni文件夾中。
# include <jni.h> # include <stdio.h> extern "C" { /*表示返回一個字符串 方法名稱格式:Java_包名_類名_方法名(這個方法名java要調用的)
*參數
*1. JNIEnv:代表了VM里面的環境,本地的代碼可以通過該參數與Java代碼進行操作
*2. obj:定義JNI方法的類的一個本地引用(this)
*/
JNIEXPORT jstring JNICALL Java_com_hong_demo_MyNative_getInfo(JNIEnv *env, jobject obj ){
return env -> NewStringUTF("Hello,樹先生!");
}
}
5、jni文件夾下創建Android.mk文
LOCAL_PATH := $(call my-dir) // 設置工作目錄,而my-dir則會返回Android.mk文件所在的目錄 include $(CLEAR_VARS) // 清除幾乎所有以LOCAL——PATH開頭的變量(不包括LOCAL_PATH) LOCAL_MODULE := hello_jni // 設置模塊的名稱,即編譯出來.so文件名 // 注,要和上述步驟中build.gradle中NDK節點設置的名字相同 LOCAL_SRC_FILES := test.cpp // 指定參與模塊編譯的C/C++源文件名 include $(BUILD_SHARED_LIBRARY) // 指定生成的靜態庫或者共享庫在運行時依賴的共享庫模塊列表。
6、jni文件夾下創建Application.mk文件
APP_ABI := armeabi armeabi-v7a // 最常用的APP_ABI字段:指定需要基於哪些CPU平台的.so文件 // 常見的平台有armeabi x86 mips,其中移動設備主要是armeabi平台 // 默認情況下,Android平台會生成所有平台的.so文件,即同APP_ABI := armeabi x86 mips // 指定CPU平台類型后,就只會生成該平台的.so文件,即上述語句只會生成armeabi平台的.so文件
7、編譯生成so文件。控制終端進入jni目錄,執行 ndk-build 命令即可。
8、本地調用so文件中的方法。
// 步驟1:加載生成的so庫文件 // 注意要跟.so庫文件名相同 static { System.loadLibrary("ImgFun"); } // 步驟2:定義在JNI中實現的方法 public native String getInfo();
9、整體代碼結構
最后說明,有幾點參考的文章: https://www.jianshu.com/p/38859f881888 質量和畫風都非常贊呢~