Android NDK jni 使用

NDK 配置編譯

一、配置NDK路徑

1.右鍵項目名稱。
2.選擇open modules settings
3.選擇SDK Location選項卡。
4.設置Android NDK location的路徑(例如我的路徑爲 C:\sdk\ndk-bundle)。

二、Java調用方法

例如我在文件com.uso6.www.ndktest.MainActivity中加入Java的調用方法。

public native String getResult();

static {
	System.loadLibrary("myNdk");
}

三、生成調用頭文件

使用命令行,進入java目錄, 然後使用命令 javah
javah的使用:javah -d <路徑> <包名>.<類名>

我使用的命令爲javah -d ../jni com.uso6.www.ndktest.MainActivity

調用命令之後,會在java文件夾的同級生成一個jni文件夾,jni文件夾下有一個com_uso6_www_ndktest_MainActivity.h頭文件。

四、實現頭文件功能

jni目錄下新建hi.c(名字隨便取.c/.cpp都行)。
hi.c內容如下:

#include "com_uso6_www_ndktest_MainActivity.h"
/*
 * Class: com_uso6_www_ndktest_MainActivity
 * Method: getResult
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_uso6_www_ndktest_MainActivity_getResult (JNIEnv* env, jobject obj){
	return (*env)->NewStringUTF(env, "Hello Test NDK!");
}

五、修改配置

1.在gradle.properties末尾加入:android.useDeprecatedNdk=true
2.在build.gradle(Module app)defaultConfig裏面加入ndk支持。

    ndk {
        moduleName "myNdk"
        ldLibs "log", "z", "m"
        abiFilters "armeabi", "armeabi-v7a", "x86"
    } 

六、運行

在需要調用的地方使用getResult()即可。


Cmake 配置編譯

文件結構如下圖所示:
文件結構

一、配置build.gradle

1.在android裏面的defaultConfig中加入

externalNativeBuild {
	cmake {
		cppFlags ""
		// 生成多個版本的so文件
		abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86','x86_64'
	}
}

2.在android中加入

// 配置CMakeLists.txt路徑
externalNativeBuild {
	cmake {
		path "CMakeLists.txt"  // 設置所要編寫的c源碼位置,以及編譯後so文件的名字
	}
}

二、配置CMakeLists.txt

1.在項目的app文件夾下新建CMakeLists.txt

# CMake 的最小版本
cmake_minimum_required(VERSION 3.4.1)

# C 的編譯選項是 CMAKE_C_FLAGS
# CMAKE_CXX_FLAGS
# CMAKE_CXX_FLAGS_DEBUG/CMAKE_CXX_FLAGS_RELEASE
# 指定編譯參數,可選
# SET(CMAKE_CXX_FLAGS "-Wno-error=format-security -Wno-error=pointer-sign")

# so輸出路徑 CMAKE_LIBRARY_OUTPUT_DIRECTORY
# 設置生成的so動態庫最後輸出的路徑, 獲取當前編譯的abi , ANDROID_ABI
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})

# 設置頭文件搜索路徑(和此txt同個路徑的頭文件無需設置),可選
#INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/common)

# 指定用到的系統庫或者NDK庫或者第三方庫的搜索路徑,可選。
#LINK_DIRECTORIES(/usr/local/lib)

# 配置頭文件的包含路徑
# include_directories(${PROJECT_SOURCE_DIR}/src/main/cpp/)

add_library(
    one
    SHARED
    src/main/cpp/OneNative.cpp
)

set_target_properties(
    one
    PROPERTIES IMPORTED_LOCATION
    ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libone.so
)

find_library(
    log-lib
    log
)

target_link_libraries(
    one
    ${log-lib}
)
# 添加子目錄,將會調用子目錄中的CMakeLists.txt
ADD_SUBDIRECTORY(src/main/cpp/two)

2.在項目的app/src/main/cpp/two文件夾下新建CMakeLists.txt。

# CMake 的最小版本
cmake_minimum_required(VERSION 3.4.1)

add_library(
    two
    SHARED
    TwoNative.c
)

set_target_properties(
    two
    PROPERTIES IMPORTED_LOCATION
    ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libtwo.so
)

find_library(
    log-lib
    log
)

target_link_libraries(
    two
    ${log-lib}
)

三、Java調用方法

新建類OneJni.java和TwoJni.java。

package uso6.com.cmake;
public class OneJni {

    static {
        System.loadLibrary("one");
    }

    public native String getString();

}
package uso6.com.cmake;
public class TwoJni {

    static {
        System.loadLibrary("two");
    }

    public native String getString();

}

四、生成調用頭文件

使用命令行,進入java目錄, 然後使用命令 javah
javah的使用:javah -d <路徑> <包名>.<類名>

我使用的命令爲:
javah -d ../cpp uso6.com.cmake.OneJni
javah -d ../cpp/two uso6.com.cmake.TwoJni

注: 如果使用的是JDK10以上, 沒有 javah 命令,需要用
javac -h ../cpp uso6.com.cmake.OneJni.java
javac -h ../cpp/two uso6.com.cmake.TwoJni.java
代替。

調用命令之後,會在java文件夾的同級生成一個cpp文件夾,cpp文件夾下有一個uso6_com_cmake_OneJni.h頭文件和two文件夾,在two文件夾下有一個uso6_com_cmake_TwoJni.h頭文件。

五、實現頭文件功能

cpp目錄下新建OneNative.cpp
OneNative.cpp內容如下:

#include "uso6_com_cmake_OneJni.h"

JNIEXPORT jstring JNICALL Java_uso6_com_cmake_OneJni_getString
  (JNIEnv *env, jobject object) {
    return env->NewStringUTF("I am one.");
  }

two目錄下新建TwoNative.c
TwoNative.c內容如下:

#include "uso6_com_cmake_TwoJni.h"
JNIEXPORT jstring JNICALL Java_uso6_com_cmake_TwoJni_getString
  (JNIEnv *env, jobject object) {
    return (*env)->NewStringUTF(env, "I am two.");
  }

六、運行

在需要調用的地方使用OneJni和TwoJni類即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章