Pages

星期一, 8月 24, 2015

[android] 使用NDK與jni編譯原生C語言程式碼

因為使用NDK+jni來使得原生的C/C++程式可供Android應用程式呼叫,似乎與開發環境(Android Studio或Eclipse)以及NDK版本有關,不同的開發環境在設定/目錄結構上似乎有些微的不同,因此將自己嘗試成功的例子記錄下來,以供大家參考。



1. 設定外部工具

  • File→Settings→External Tools
  • 新增 NDK Build

Name: NDK Build
Group: NDK
Description: NDK Build
Options: 全打勾
Show in: 全打勾
Tools Settings:
Program: NDK目錄/ndk-build.cmd
Parameters: NDK_PROJECT_PATH=$ModuleFileDir$/build/intermediates/ndk NDK_LIBS_OUT=$ModuleFileDir$/app/src/main/jniLibs NDK_APPLICATION_MK=$ModuleFileDir$/app/src/main/jni/Application.mk APP_BUILD_SCRIPT=$ModuleFileDir$/app/src/main/jni/Android.mk V=1
Working directory: $SourcepathEntry$

  • 新增 Javah

Name: Javah
Group: NDK
Description: Javah
Options: 全打勾
Show in: 全打勾
Tools Settings:
Program: Java JDK目錄/binjavah.exe
Parameters: -v -jni -d $ModuleFileDir$/src/main/jni $FileClass$
Working directory: $SourcepathEntry$

2. 相關檔案設定

  • 在local.properties中新增

ndk.dir=NDK安裝目錄

  • 在build.gradle中新增你想要呼叫的模組名稱,在這邊為JniTest

android {
   ...
   ...
   defaultConfig {
       ...
       ...
       ndk {
           moduleName "JniTest"
       }
   }
}

  • 在主程式MainActivity.java中加上載入JniTest模組程式碼

static {
   System.loadLibrary("JniTest");
}
public native String getStringFromNative();

3. 新增JNI檔案

  • 在app/src/main下新增一jni目錄
  • 新增src/main/jni/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JniTest
LOCAL_SRC_FILES := JniTest.c
include $(BUILD_SHARED_LIBRARY)

  • 新增src/main/jni/Application.mk

APP_ABI := all

  • 新增src/main/jni/JniTest.c

#include <jni.h>
JNIEXPORT jstring JNICALL Java_com_myapplication_MainActivity_getStringFromNative (JNIEnv *evn, jobject obj) {
   return (*evn)->NewStringUTF(evn,"Hello NDK demo");
}

4. 使用NDK Build建置

  • 切換到Project模式
  • 編輯設定檔,在build.gradle中加上

android {
   ...
   ...
   sourceSets.main.jni.srcDirs = []
   ...
}

  • 在專案目錄按右鍵 -> NDK -> NDK Build
  • 建置完成後會產生 app/src/main/jniLibs 資料夾,so檔就在裡面

5. 執行前

  • 在project目錄下的gradle.properties加上

android.useDeprecatedNdk=true

6. 調用javah協助JNI相關檔案建置(optional)

  • 使用javah產生header
    • 在MainActivity.java按右鍵 -> NDK -> Javah
    • 執行完畢後,在jni目錄中會出現 com_mayapplication_MainActivity.h
  • 再進行3. 新增JNI檔案


沒有留言:

張貼留言