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文件