jni.h頭文件
- 定義了java和C語言之間進行數(shù)據(jù)對應(yīng)的關(guān)系
- 在結(jié)構(gòu)體內(nèi)部封裝了java和C語言之間進行數(shù)據(jù)轉(zhuǎn)換的函數(shù)指針
JNIEnv typedef const struct JNINativeInterface* JNIEnv;
- JNIEnv *env
- typedef struct JNINativeInterface* JNIEnv;
- struct JNINativeInterface*<=>JNIEnv 結(jié)構(gòu)體一級指針
- env<=>JNIEnv <=> struct JNINativeInterface*二級指針
- (*env)->NewStringUTf
JNI開發(fā)涉及到的概念
- 交叉編譯 在host平臺下為目標(biāo)平臺(target)編譯代碼 taget平臺不足以支撐編譯
- 平臺 操作系統(tǒng) windows linux macos
- cpu架構(gòu):x86 arme mips 指令集不同
- 工具鏈
動態(tài)庫和靜態(tài)庫區(qū)別
- 動態(tài)庫 linux .so windows .dll 小 共享庫
- 靜態(tài)庫 linux .a windows libs 大
jni開發(fā)用到的工具
NDK目錄結(jié)構(gòu)
- native development kit 本地開發(fā)工具集
- build/core/下面有很多mk文件饶氏,指導(dǎo)工程構(gòu)建和編譯的配置文件 像建筑圖紙
- doc下面開發(fā)文檔
- platforms提供函數(shù)庫的頭文件和庫文件
- prebuilt各個平臺的調(diào)試工具 windows下make.exe 工程管理器 相當(dāng)于建造大樓的監(jiān)工(按照圖紙進行監(jiān)工)
- sample 谷歌工程師寫的例子
- source第三方庫 不關(guān)心
- toolchains 交叉編譯工具鏈,相當(dāng)于農(nóng)民工 toolchains\x86-4.4.3\prebuilt\windows\bin下有很多工具鏈古程,只需要配置好配置文件用好mk工具喊崖,會自動調(diào)里面的工具鏈
- test 在linux環(huán)境下可以執(zhí)行run-tests.sh腳本,測試當(dāng)前環(huán)境是否配置好 Windows下跑不了
- ndk-build.cmd 谷歌包裝好的make工具 怎么用呢茁裙?在當(dāng)前文件夾下按住shift 右鍵-在此處打開命令行窗口-ndk-build -v回車 make工具 可以對照make里面看看 沒必要掌握make復(fù)雜的用法节仿,只需要用谷歌包裝好的ndk-build.cmd就行
JNI開發(fā)流程
eclipse開發(fā)jni
開發(fā)流程一
-
1.定義本地方法
- public native String hello();
2.在工程下創(chuàng)建jni目錄
-
3.創(chuàng)建hello.c源文件
#include <jni.h> //包含jni.h頭文件 java和c相互對應(yīng) 以及相互轉(zhuǎn)換方法 /** * 函數(shù)名:Java_包名(包名中.以_代替)_類名_方法名 * JNIEnv *env結(jié)構(gòu)體二級指針 java和C語言數(shù)據(jù)轉(zhuǎn)換的函數(shù)指針 * jobject obj:調(diào)用當(dāng)前函數(shù)的java類 C語言調(diào)用java方法時需要用到 */ jstring Java_com_itheima_hello_MainActivity_hello(JNIEnv *env,jobject obj){ char *buf="hello from c"; return (*env)->NewStringUTF(env,buf); }
-
4.創(chuàng)建Android.mk文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello #指定生成的庫名 lib庫名.so LOCAL_SRC_FILES := hello.c #編譯的C語言源文件 如果有多個源文件 空格依次排開 include $(BUILD_SHARED_LIBRARY) #指定生成動態(tài)庫
-
5.創(chuàng)建Application.mk文件
APP_ABI := armeabi armeabi-v7a x86 #指定生成的庫的平臺
6.進入到j(luò)ni目錄執(zhí)行ndk-build命令生成so庫(libs)
-
7.程序運行時加載so庫
static{ System.loadLibrary("hello"); }
eclipse集合ndk開發(fā)
- 1.配置ndk路徑 windows-prefreence-android-ndk
- 2.定義本地方法
- public native String hello();
- 3.右鍵-Android Tools-Add native support (指定生成的so庫名)
- 4.編寫配置文件和C語言源文件
- 5.在程序運行時加載so庫
- 6.運行程序 自動生成so庫
as中開發(fā)jni
第一種開發(fā)方式
-
1.定義本地方法
- public native String hello();
2.在工程下創(chuàng)建jni目錄
3.創(chuàng)建hello.c源文件
4.創(chuàng)建Android.mk文件
5.創(chuàng)建Application.mk文件
6.進入到j(luò)ni目錄執(zhí)行ndk-build命令生成so庫(libs)
-
7.指定so路徑 在module的build.gradle下
sourceSets{ main{ jniLibs.srcDirs=['libs'] } }
-
8.程序運行時加載so庫
static{ System.loadLibrary("hello"); }
as結(jié)合ndk開發(fā)
-
1.配置ndk路徑
- 工程結(jié)構(gòu)-ndk路徑(自己下載)
2.定義本地方法
3.創(chuàng)建jni folder
4.編寫C語言源文件
-
5.module的build.gradle下defaultConfig標(biāo)簽下
ndk{ moduleName "hello" #庫名 abiFilters "armeabi","armeabi-v7a","x86" #平臺 }
6.程序運行時加載so庫
-
7.運行生成so庫
- so庫在build-中間文件-ndk-debug-lib
android.useDeprecatedNdk=true
- so庫在build-中間文件-ndk-debug-lib
Cmake方式開發(fā)jni 跨平臺
1.定義本地方法
2.main下創(chuàng)建cpp目錄
3.cpp下創(chuàng)建C語言源文件
-
4.創(chuàng)建CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1) add_library( # 指定生成的庫名 hello # 指定生成動態(tài)庫 SHARED #指定編譯的源文件 如果有多個源文件需要全路徑拷貝依次排開 src/main/cpp/hello.c ) #查找jni環(huán)境提供的庫 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 ) # 鏈接庫 target_link_libraries( # 鏈接自己生成的庫 和上面生成的庫名保持一致 hello # 鏈接log庫 ${log-lib} )
-
5.關(guān)聯(lián)CMakeLists.txt
- 右鍵mudole-Link C++ project with gradle-選擇CMakeLists.txt路徑
-
6.指定生成的平臺 在build.gradle的defaultConfig
- externalNativeBuild {
cmake {
abiFilters "armeabi","armeabi-v7a","x86"
}
}
- externalNativeBuild {
7.加載so庫
8.運行生成so庫 build-中間文件-cmake-debug-obj