JNI項目搭建

交叉編譯

  • 在一個平臺上去編譯另一個平臺上可以執行的本地代碼
  • 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類的全類名

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容