標籤:
1. 建立一個工程,並添加JNI檔案夾。
2. 在產生的jni檔案夾中添加cpp檔案。
3. 在添加的cpp檔案添加代碼。這裡我們採用動態註冊的方式來添加jni函數,比較方便,不需要用javah產生.h檔案
#include <jni.h>#include <android/log.h>#include <assert.h>#include <stdio.h>/* 輸出Log的宏 */#ifndef LOG#define LOG_TAG "imgprocess"#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__);#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__);#endif LOG#ifndef NELEM# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))#endifjstring native_hello(JNIEnv* env, jobject thiz){ return env ->NewStringUTF("hello world from jni~");}//native函數所在java類的位置static const char *classPathName = "com/test/hc/MainActivity";// 映射表,這裡將我們java函數和c函數對應起來static JNINativeMethod gMethods[] = { {"native_hello", "()Ljava/lang/String;", (void*)native_hello},};int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods){ jclass clazz; clazz = env->FindClass(className); if (clazz == NULL) { ALOGE("Native registration unable to find class '%s'", className); return JNI_FALSE; } if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { ALOGE("RegisterNatives failed for '%s'", className); return JNI_FALSE; } return JNI_TRUE;}//staticint register_my_jni_methods(JNIEnv* env){ return registerNativeMethods(env, classPathName, gMethods, NELEM(gMethods));}// 在我們load該so庫的時候,JNI_OnLoad將會自動被調用,來註冊JNI函數jint JNI_OnLoad(JavaVM* vm, void*){ JNIEnv* env = NULL; jint result = -1; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { ALOGE("ERROR: GetEnv failed\n"); goto bail; } assert(env != NULL); if (register_my_jni_methods(env) < 0) { ALOGE("ERROR: native registration failed\n"); goto bail; } ALOGE("SUCCESS: native registration successed\n"); result = JNI_VERSION_1_4; bail: return result;}
4. 在app的build.properties如下位置,添加ndk編譯項
moduleName:產生so庫的名字ldLibs:連結時使用的庫,由於我們要列印log,所以需要引用abiFilters:產生哪些abi體系架構的so庫
5. 在gradle.properties中添加android.useDeprecatedNdk=true
不然會出現如下錯誤:
Error:(14, 0) Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.
6. 在local.properties中配置ndk路徑
7. 在MainActivity載入so庫,並聲明native函數
8. 啟動並執行時候發現NDK報錯,這是NDK在windows下的一個bug,當僅僅編譯一個檔案的時候就會出現此問題,解決辦法是再往jni檔案夾加入一個空的cpp檔案即可,ndk產生的so檔案在app/build/intermediates/ndk/debug/lib目錄下,會自動打包到apk中:
最後運行結果
Android Studio JNI編程以及NDK環境配置