Android JNI 系列
[TOC]
Android JNI 基本知识
1.1 什么是JNI
JNI (Java Native Interface)
,它提供了若干API
使得Java
可以和其他语言互通,是JDK
的一部分.
理解这些就可以了!
1.2 为什么使用JNI
使用JNI
是为了将现有的C或C++
库集成到使用Java
语言开发的应用中,或者有些性能要求较高的场景下,使用C
或C++
才能满足的场景.
1.3 使用JNI带来的问题
程序不再跨平台,还有JNI带来的内存问题,以及可能引起的Crash
使用Android Studio 搭建JNI开发环境
目前使用Android Studio 3.0
可以直接建立一个支持C或C++
语言的JNI
项目.
如果需要将现有的应用集成JNI
可参照Google Dev
的官方文档操作.
编译JNI
程序,可以使用NDK
编译,或者使用CMAKE
来编译,现在来讲都可行,推荐使用CMAKE
来编译.
在app
目录下建立一个JNI目录
源文件都放到这里.
注意目录名称是JNI
,只是在Android Studio
中显示为cpp目录
下面写CMAKE文件
# 这里使用的是bsdiff patch的JNI库例子.
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
# 设置CMake编译器的版本
cmake_minimum_required(VERSION 3.4.1)
# 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.
# 声明源文件路径
file(GLOB bzip "src/main/jni/bzip2/*.c")
file(GLOB bs_src "src/main/jni/*.c")
# 引入头文件路径 (这里必须要引入)
include_directories(
"src/main/jni/bzip2/"
)
# 引入源文件
add_library( # Sets the name of the library.
# 设置编译后的库名称
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
# 设置源文件的位置
${bzip}
src/main/jni/native-lib.c )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
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 )
# 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.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
简单的来一个JNI HelloWorld
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public static native String helloworld();
}
#include <jni.h>
JNIEXPORT jstring JNICALL
Java_com_sankuai_meituan_testjni_MainActivity_helloworld(JNIEnv *env, jclass type) {
return (*env)->NewStringUTF(env, "hello world");
}
从C
的函数定义中可以发现,函数的签名是有一定规律的一般是下面这种格式
Java_[包名]_[类名]_[方法名](JNIEnv * env,jclass type,[params])