[TOC]

Android JNI 基本知识

1.1 什么是JNI

JNI (Java Native Interface),它提供了若干API使得Java可以和其他语言互通,是JDK的一部分.

理解这些就可以了!

1.2 为什么使用JNI

使用JNI是为了将现有的C或C++库集成到使用Java语言开发的应用中,或者有些性能要求较高的场景下,使用CC++才能满足的场景.

1.3 使用JNI带来的问题

程序不再跨平台,还有JNI带来的内存问题,以及可能引起的Crash

使用Android Studio 搭建JNI开发环境

目前使用Android Studio 3.0可以直接建立一个支持C或C++语言的JNI项目.

如果需要将现有的应用集成JNI可参照Google Dev的官方文档操作.

编译JNI程序,可以使用NDK编译,或者使用CMAKE来编译,现在来讲都可行,推荐使用CMAKE来编译.

app目录下建立一个JNI目录源文件都放到这里.

error

jni2

注意目录名称是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) &#123;
    return (*env)->NewStringUTF(env, "hello world");
&#125;

C的函数定义中可以发现,函数的签名是有一定规律的一般是下面这种格式

Java_[包名]_[类名]_[方法名](JNIEnv * env,jclass type,[params])

Comments

2017-12-27

⬆︎TOP