一 环境搭建
本文讲解的是在一个现有的工程中增加JNI的支持。
我们从新建一个工程说起,本文假设你已经知道怎么设置sdk和ndk。
新建工程的时候我们故意不勾选这个选项,方便后面说明。
一直默认点下一步,直到工程创建完成。
工程创建完成之后是这样的
打开SDK manager注意这两个包要下载下来
然后新建一个jni目录,如下图
好好看,这个jni文件夹的颜色和java的颜色不一样
二 声明本地方法
我这里在java层声明了三个本地方法,并在java代码中调用他们。
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.textView);
String strFormJni = StartJni();
tv.setText(strFormJni);
}
public native String StartJni();
public native void EndJni();
public native void JniProcess();
}
三 新建jni目录
在jni目录下新建三个文件Android.mk Application.mk hello.cpp
Android.mk
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=hello
LOCAL_SRC_FILES :=hello.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_MODULES := hello
APP_PLATFORM := android-28
NDK_LIBS_OUT=src/main/jniLibs
APP_ABI := all
APP_OPIM :=debug
hello.cpp
在cpp文件中实现MainActivity.java中声明的三个本地方法。这里采用的是动态注册的方法。
#include #include extern "C"{
//JNIEXPORT : 导出函数符号表
JNIEXPORT jstring native_init(JNIEnv* env, jobject obj);
JNIEXPORT void native_exit(JNIEnv* env, jobject obj);
JNIEXPORT void native_process(JNIEnv* env, jobject obj);
}
jstring native_init(JNIEnv* env, jobject obj)
{
// LOGI("native init is called");
int m;
m += 10;
return env->NewStringUTF((const char *)"hello form JNI22");
}
void native_exit(JNIEnv* env, jobject obj)
{
// LOGI("native init is called");
}
void native_process(JNIEnv* env, jobject obj)
{
//LOGI("native init is called");
}
static JNINativeMethod gMethods[] =
{
{ "StartJni", "()Ljava/lang/String;", (void*) native_init},
{ "EndJni", "()V", (void*) native_exit},
{"JniProcess","()V",(void*)native_process}
};
jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
return JNI_ERR;
//com/example/app/NativeInterface,在这个java类中声明了本地方法,所以这里写这个方法的全路径
jclass clazz = env->FindClass("com/example/cbj_g/debugjni/MainActivity");
//注册,本地方法到VM的表中
env->RegisterNatives(clazz, gMethods,
sizeof(gMethods) / sizeof(gMethods[0]));
return JNI_VERSION_1_4;
}
/* 卸载JNI库 */
void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved)
{
//__android_log_write(ANDROID_LOG_DEBUG, "DiagMain","JNI_OnUnload");
}
四 转换工程配置
这一步是关键,右键main文件夹,选择Link C++ Project with Gradle,我们这里选择使用ndk-build的方式,project Path处选择jni目录下的Android.mk
经过上述操作之后你就发现jni目录和java目录的颜色变成一样的了。至此我们的环境都设置好了,接下来就可以愉快的debug了。
五 debug截图
jni的环境初始化函数
java调用CPP函数
java层得到返回值
源码下载地址