1:配置 Android NDK環境
2:配置Andorid Studio
- 在Gradle的 local.properties中添加配置
ndk.dir=/home/tclxa/Android/Sdk/ndk-bundle
sdk.dir=/home/tclxa/Android/Sdk
- 在Gradle的 gradle.properties中添加配置
android.useDeprecatedNdk=true
- 在Module下build.gradle中的defaultConfig添加ndk節點
//ndk編譯生成.so文件
ndk {
moduleName "hello_jni" //生成的so名字
ldLibs "log"
}
3: 在java中調用native方法:
package com.example.tclxa.ndkdemo;
public class JNIUtils {
// 步驟2:定義在JNI中實現的方法
public static native String getStringFromJNI();
}
4: 對native 方法生成對應的.h文件:
main/java$> javah -d ../jni com.example.tclxa.ndkdemo.JNIUtils
// (包名.類名), javah意思是生成一個.h頭文件,-d ../jni的意思是生成一個名字叫做jni的文件夾(directory),位置是在當前目錄(src/main/java)的上一級目錄(即src/main目錄)
5: 將.h文件拷貝到main/jni下:
com_example_tclxa_ndkdemo_JNIUtils.h文件
6: 在main/jni下實現.h對應的.c/.cpp文件:
com_example_tclxa_ndkdemo_JNIUtils.c
在c/c++代碼中加入log:
#include "com_example_tclxa_ndkdemo_JNIUtils.h"
#include <string.h>
#include <jni.h>
#include <stdlib.h>
#include <android/log.h>
#define LOGD_TAG "wwww"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOGD_TAG, __VA_ARGS__)
#define LOGI_TAG "wwww"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOGI_TAG, __VA_ARGS__))
JNIEXPORT jstring JNICALL Java_com_example_tclxa_ndkdemo_MainActivity_getStringFromJNI(JNIEnv * env,
jobject jobject){
LOGI("native function start..");
LOGI("native function over..");
return (* env)-> NewStringUTF(env,"Hello, I'm from jni");
}
7: 在main/jni下編寫Android.mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
// so文件名
LOCAL_MODULE := hello_jni
// c/c++文件
LOCAL_SRC_FILES := com_example_tclxa_ndkdemo_JNIUtils.c
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
8: 在main/jni下編寫Application.mk文件:
APP_PLATFORM := android-16
APP_ABI := armeabi-v7a
9: 運行NDK編譯命令:
main/jni$> ndk-build
編譯成功後,在src/main/會多了兩個文件夾libs & obj,其中libs下存放的是.so庫文件
10: 在src/main/中創建一個名爲jniLibs的文件夾:
將so文件夾複製到jniLibs下
參考博文
- 大佬博客
- JNI詳解
- 生成.h、so文件