over 6 years ago

如何在 Android Studio 中使用 NDK 編譯 JNI

定義 Native 方法


  • 新增 NativeLib.java 在下圖中的路徑

  • NativeLib.java

    package com.demo.jnidemo;
    
    public class NativeLib {
        static{
            System.loadLibrary("native");
        }
    
        public native String getHelloMessage();
    }
    

撰寫 Native Code (C/C++)


  • [app/src/main] 路徑下建立 jni 資料夾,並在資料夾中新增檔案: native.cpp。要注意的是,路徑及資料夾名稱都是 Android Studio 的預設規則,需正確對應才能順利編譯。

  • native.cpp

    #include <jni.h>
    
    extern "C" {
    
        JNIEXPORT jstring JNICALL Java_com_demo_jnidemo_NativeLib_getHelloMessage( JNIEnv* env, jobject object){
            return env->NewStringUTF("Hello, JNI.");
        }
    
    }
    

設定 NDK 路徑


如果之前沒有在環境變數中加入 NDK 的路徑,編譯時會遇到 > NDK not configured. 的錯誤。需要在專案根目錄下的 local.properties 檔案中設定 ndk.dir 變數。

sdk.dir=/your-sdk-path
ndk.dir=/your-ndk-path

設定 Android.mk 參數


AndroidStudio 的預設行為,在編譯時會自動生成 Android.mk 檔,路徑位於:app/build/intermediates/ndk/[debug/release]/Android.mk。可以透過設定 app 目錄下的 build.gradle 來修改。

  • build.gradle

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 21
        buildToolsVersion "21.1.1"
    
        defaultConfig {
            applicationId "com.demo.jnidemo"
            minSdkVersion 17
            targetSdkVersion 21
            versionCode 1
            versionName "1.0"
    
            ndk{
                moduleName "native"
                //cFlags "-DANDROID_NDK -D_RELEASE"
                //ldLibs "m", "log", "jnigraphics"
                //abiFilters "armeabi", "armeabi-v7a"
                //stl "stlport_static"
            }
        }
    
        ....
    
  • 在 ndk 區塊中可以設定的參數如下

    • moduleName : 編譯出的 .so 名稱
    • cFlags:對應生成模式
    • ldlibs:對應 LOCAL_LDLIBS,需去掉前綴的 "l"
    • abiFilters:對應 APP_API
    • stl:對應 APP_STL

Build and Run


加上測試程式碼

String str = NativeLib.getHelloMessage();
Log.d("", str);

編譯後在 logcat 可看到訊息

Hello, JNI.
← [Git] How to fetch a new remote branch
 
comments powered by Disqus