android 系统中Application和ApplicationFramework都是用java写的,底层和使用众多的库都是C/C++都是写的。但是jni的调用有两种方式:静态方法和动态注册。下面我先介绍静态方法。
静态方法
- 首先创建一个java类,然后声明native方法,可以是静态方法,也可以普通方法
这第二步要创建一个头文件,然后在这个头文件中声明这些native函数。这个头文件可以可以自己写,也可以用命令生成(javah)。这个函数的声明方式是Java_package_class_funtionname。注意最前面的Java不能省(我在写的时候因为没注意这个找了好半天,才发现这个错误,也是自己粗心大意)。package也必须要用下划线隔开。我用的是android studio。
配置android studio的javah
头文件中定义函数的例子
3.下面是实现头文件的函数,这个地方没啥好说的会写C语言,这点难不倒,如果不会只能去学习了
4.最后是编译成库在java中引用。
现在的编译库有两种方式一种以CMake,一种是NDK编译。这里我只简单介绍Cmake的编写方式。
cmake_minimum_required(VERSION 3.4.1)//这里指的Cmake的版本
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
static //要生成库的名字
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/static_jni.cpp )//这里是要编译的c/c++的文件
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )//找到log文件
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
static
# Links the target library to the log library
# included in the NDK.
${log-lib} )
动态注册
动态注册不用写native方法的头文件。但是需要在加载库文件的时候注册这些native方法。通过以下步骤可以完成静态注册实现JNI的调用。
- 首先创建java类,声明native方法,跟静态哪一步一样。
创建C/C++文件。
3.实现 JNI_OnLoad方法(在java中调用System.loadLibrary(“dynamic”)时会在C中调用这个方法)。jni中有JNINativeMethod结构。注册函数需要通过这个结构实现。JNINativeMethod结构:
注册函数:
JNINativeMethod结构数组:
4.实现JNINativeMethod结构中指针函数,然后进行编译,跟静态中的编译方法一样。
数据类型转换
基本数据类型转换表:
java引用数据类型转换:
JNIl类型签名
类型标识示意表:
函数签名例子:
java 方法 | 参数或者返回值签名 |
---|---|
public native String getString(); | ()Ljava/lang/String; |
public native double getDouble(); | ()D |
public native void setString(String str); | (Ljava/lang/String;)V |