Android NDK开发相关知识集合

来源:互联网 发布:啊沁的淘宝店 编辑:程序博客网 时间:2024/06/04 17:53

1.关于方法名
调用 native 方法之前,首先要调用 System.loadLibrary 接口加载一个实现了native 方法的动态库才能正常访问,否则就会抛出 java.lang.UnsatisfiedLinkError 异常,找不到 XX 方法的提示。现在我们想想,在 Java 中调用某个 native 方法时,JVM 是通过什么方式,能正确的找到动态库中 C/C++ 实现的那个 native 函数呢?

JVM 查找 native 方法
JVM 查找 native 方法有两种方式:

按照 JNI 规范的命名规则
调用 JNI 提供的 RegisterNatives 函数,将本地函数注册到 JVM 中。(后面会详细介绍)
比如Java层 HelloWorld 类中有一个sayHello方法 其命名规则为 Java_com_study_jnilearn_HelloWorld_sayHello

package com.example.testndkeclipse;public class JniClient {    static public native String AddStr(String strA, String strB);    static public native int AddInt(int a, int b);}

jni层对应的c文件

com_example_testndkeclipse_JniClient.c

方法为

JNIEXPORT jstring JNICALL Java_com_example_testndkeclipse_JniClient_AddStr  (JNIEnv *env, jclass arg, jstring instringA, jstring instringB)

使用的时候加载动态库

static {        // 加载so库        System.loadLibrary("TestNdk");// lib和.so为前缀后缀,不用加上    }

再在java层中调用即可

String strFromC = JniClient.AddStr("Java2C_参数1", "Java2C_参数2");

2.关于Android.mk文件
Android.mk文件用来告诉NDK编译系统,应该如何编译这些源码。更确切地说,该文件其实就是一个小型的Makefile。你可以在每一个android.mk file中定义一个或多个模块。每个模块属下列类型之一: 
1)APK程序,一般的Android程序,编译打包生成apk文件 
2)Java库,java类库,编译打包生成jar文件 
3)  C\C++应用程序,可执行的C\C++应用程序 
4)C\C++静态库,编译生成C\C++静态库,并打包成.a文件 
5)C\C++共享库, 编译生成共享库(动态链接库),并打包成.so, 有且只有共享库才能被安装/复制到您的应用软件(APK)包中。

简单的理解为配置文件。

3.关于JNIEnv

在每一个native的C/C++实现的函数声明我们都能看到,除了函数本身的参数,在传入时还传递了一个JNIEnv函数和jclass或者jobject函数。
JNIEnv是一个结构,里面提供了许多进行Java和C/C++进行数据转换和处理的函数。在调用到native代码时实际上传入了由JVM创建的JNIEnv结构的指针,在这个结构内就是java执行栈中的一些数据等内容供native代码进行操作。由于传入的JNIEnv是一个指针,因此使用其中的函数需要以下语法:

(*env)->方法名(env,参数列表) //C的语法
env->方法名(参数列表) //C++的语法

这是由于C语言没有对象的概念,因此要将env指针作为形参传入到JNIEnv方法中。

代码已上传至Github

如有不正支出,欢迎留言交流!
我的GitHub
我的CSDN
我的简书
开发笔记

原创粉丝点击