熟悉安卓四层架构的朋友们都了解,安卓的四层架构自上至下分别是应用层、应用框架层、函数库(也包括Android Runtime)、Linux内核层,其中上面两层是JAVA实现的,而底层则是so库、驱动等组成。从安卓的四层架构,我们可以理解为安卓应用是由JAVA开发的,但是底层是由C、C++等其他语言支持。
既然安卓的底层是其他语言,那么咱们用JAVA实现的APP是如何与底层交互的呢?在这里,需要了解一个概念,那就是JNI。何谓JNI,他的全名叫Java Native Interface,他支持JAVA与其他语言(如C、C++)进行交互通信,并提供了若干的API。虽然JAVA调用其他语言开发的库可能会使平台丧失可移植性,但是有些需求是必须要这么做的。JAVA虽然具有跨平台性(三个版本支持大多数的平台),但是有些功能是其无法实现,或者无法完美实现的,这就需要用其他语言实现。
接下来,让我们一起通过一个例子来认识一下JNI的用法(NDK环境的配置就不再赘述):
1、第一步在项目工程新建一个一个jni目录,并新建一个Android.mk文件和一个SaveKey.c文件
mk文件是一个编译文件,用来描述源文件,主要用于声明源文件路径、模块名、平台版本以及源文件名等信息
SaveKey.c文件对于C、C++开发人员来说再熟悉不过了,在c文件中声明引入的库,并定义相关变量和两个方法,分别是SaveKey与GetKey,代码如下:
JNIEXPORT void JNICALL Java_com_example_savekey_MainActivity_saveKey
(JNIEnv *env, jobject thiz,jstring strName)
{ jboolean iscopy;
keyStr = (*env)->GetStringUTFChars(env, strName,&iscopy);
LOGD("input keystr : %s", keyStr);
//(*env)->ReleaseStringUTFChars(env, strName, keyStr);
}
JNIEXPORT jstring JNICALL Java_com_example_savekey_MainActivity_getKey
(JNIEnv *env, jobject thiz)
{
jstring StringArg = (*env)->NewStringUTF(env,keyStr);
return StringArg;
}
特别要注意方法名字的定义,规则如下“应用包名_Activity名字_方法名”
第二步,声明方法
代码如下:
public native void saveKey(String strName);
public native String getKey();
需要注意的是方法名要与c文件中定义的一致,并不要忘记native这个关键词
第三步,加载模块
在第一步咱们再mk文件中声明了模块名,咱们在Activity中需要用这个模块名来加载,代码如下:
System.loadLibrary("save_key");
上面代码中的save_key便是我们在第一步中声明的模块名
第四步,方法调用
saveKey("tanguigui");
如果前两步没出什么问题的吧,上述代码就可以运行了,执行完之后可以通过getkey获取数据并打印进行测试
感谢观看~