交叉編譯
- 在一個平臺上去編譯另一個平臺上可以執行的本地代碼
- cpu平臺 arm x86 mips
- 操作系統平臺 windows linux mac os
- 原理 模擬不同平臺的特性去編譯代碼
jni開發工具
- ndk native develop kit
- ndk目錄
- docs 幫助文檔
- platforms 好多平臺版本文件夾 選擇時選擇項目支持的最小版本號對應的文件夾
- 每一個版本號的文件夾中放了 不同cpu架構的資源文件
- include文件夾 jni開發中常用的 .h頭文件
- lib 文件夾 google打包好的 提供給開發者使用的 .so文件
- samples google官方提供的樣例工程 可以參考進行開發
- android-ndk-r9d\build\tools linux系統下的批處理文件 在交叉編譯時會自動調用
- ndk-build 交叉編譯的命令
- cdt eclipse的插件 高亮C代碼 C的代碼提示
jnihelloworld
jni開發的步驟
①寫java代碼 聲明本地方法 用到native關鍵字 本地方法不用去實現
②項目根目錄下創建jni文件夾
-
③在jni文件夾下創建.c文件
- 本地函數命名規則: Java_包名類名本地方法名
- JNIENV* env JNIEnv 是JniNativeInterface這個結構體的一級指針
- JniNativeInterface這個結構體定義了大量的函數指針
- env 就是結構體JniNativeInterface這個結構體的二級指針
- (*env)->調用結構體中的函數指針
- 第二個參數jobject 調用本地函數的java對象就是這個jobject
④ 導入<jni.h>
-
⑤ 創建Android.mk makefile 告訴編譯器.c的源文件在什么地方,要生成的編譯對象的名字是什么
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello #指定了生成的動態鏈接庫的名字
LOCAL_SRC_FILES := hello.c #指定了C的源文件叫什么名 字include $(BUILD_SHARED_LIBRARY)
⑥ 調用ndk-build編譯c代碼生成動態鏈接庫.so文件 文件的位置 lib->armeabi->.so
⑦ 在java代碼中加載動態鏈接庫 System.loadlibrary("動態鏈接庫的名字"); Android.mkLOCAL_MODULE所指定的名字
⑧運行:進入到項目的根目錄,cd /d 路徑-->ndk-build
jni開發中的常見錯誤
- java.lang.UnsatisfiedLinkError: Native method not found: 本地方法沒有找到
- 本地函數名寫錯
- 忘記加載.so文件 沒有調用System.loadlibrary
- findLibrary returned null
- System.loadLibrary("libhello"); 加載動態鏈接庫時 動態鏈接庫名字寫錯
- 平臺類型錯誤 把只支持arm平臺的.so文件部署到了 x86cpu的設備上
- 在jni目錄下創建 Application.mk 在里面指定
- APP_ABI := armeabi
APP_PLATFORM := android-14
- javah
- jdk 1.7 項目 src目錄下運行javah
- jdk 1.6 項目 bin目錄下 classes文件夾
- javah native方法聲明的java類的全類名
運行:cd /d (src 的路徑)-->javah native方法聲明的java類的全類名