概述
本文主要介绍
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参考 (下载地址)