概述
本文主要介绍
JNI使用在Android开发中的简单入门
环境搭建
NDK的开发是基于JNI的,下面是在Android Studio中配置NDK,按照图中的顺序依次下去,选择NDK开始下载

实例演示
native方法声明
创建一个Android项目,在MainActivity.java里声明native方法
|
|
实现native方法
在应用模块目录下创建jni目录,创建4个文件:test.cpp、test2.cpp、Android.mk、Application.mk
test.cpp实现MainActivity.java的
get和set方法1234567891011121314151617181920212223// test.cppextern "C" {jstring Java_com_jeff_customjnitest_MainActivity_get(JNIEnv *env, jobject thiz) {printf("invoke get in c++\n");return env->NewStringUTF("Hello from JNI in libjni-test.so!");}void Java_com_jeff_customjnitest_MainActivity_set(JNIEnv *env, jobject thiz, jstring string) {printf("invoke set from c++\n");char *str = (char*) env->GetStringUTFChars(string, NULL);printf("%s\n", str);env->ReleaseStringUTFChars(string, str);}}test2.cpp实现MainActivity.java的
get2()方法,此方法是用于在JNI中调用Java方法,即先通过类名找到类,再根据方法名找到方法的ID,最后调用此方法1234567891011121314151617181920212223242526272829303132// test2.cppextern "C" {void callJavaMethod(JNIEnv *env, jobject thiz) {jclass clazz = env->FindClass("com/jeff/customjnitest/MainActivity");if (clazz == NULL) {printf("find class MainActivity error!");return;}jmethodID id = env->GetStaticMethodID(clazz, "methodCalledByJni", "(Ljava/lang/String;)V");if (NULL == id)printf("find method methodCalledByJni error!");jstring msg = env->NewStringUTF("msg send by calledJavaMethod in test2.cpp");env->CallStaticVoidMethod(clazz, id, msg);}jstring Java_com_jeff_customjnitest_MainActivity_get2(JNIEnv *env, jobject thiz) {printf("invoke get in c++\n");callJavaMethod(env, thiz);return env->NewStringUTF("Hello from JNI in libjni-test.so!=====");}}Android.mk中主要描述编译时的相关配置项,描述如下
LOCAL_MODULE:模块的名称LOCAL_SRC_FILES:参与编译的源文件,有多个时使用\和换行符隔开123456789LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := jni-testLOCAL_SRC_FILES := test.cpp \test2.cppinclude $(BUILD_SHARED_LIBRARY)
Applicaiton.mk表示
CPU的架构平台类型,这里使用armeabi和x86架构,多个架构平台使用,隔开1APP_ABI := armeabi,x86
编译生成so库
进入jni目录,使用ndk-build命令编译生成so库,如下图所示,so库会存放在jni目录的对应不同架构的目录下

运行Android程序
直接运行Android应用,会发现程序无法正常运行,提示java.lang.UnstatisfiedLinkError错误,即找不到so库文件,需要制定so库所在的目录(在build.gradle中添加指定jniLibs的目录)
|
|
Note:AndroidStudio中最好指定需要打包的so库到APK中,即需要在build.gradle中添加指定abiFilters内容
|
|
参考方案
- Android开发艺术探索第十四章–JNI和NDK编程
- java.lang.UnsatisfiedLinkError 解决方法
- DEMO参考 (下载地址)