Android NDK- 认识 NDK

Posted teletian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android NDK- 认识 NDK相关的知识,希望对你有一定的参考价值。

JNI 简介

在讲 NDK 之前,先要搞清楚什么是 JNI。

定义:Java Native Interface,即 Java 本地接口。
作用: 使得 Java 与本地其他类型语言(如 C、C++)交互。也就是在 Java 中调用 C/C++ 代码,或者在 C/C++ 中调用 Java 代码。

注意,JNI 是 Java 的,和 android 无关。

NDK 简介

定义:Native Development Kit,是 Android 的一个工具开发包。

那到底 JNI 和 NDK 有什么区别呢?
NDK 可以看做是 Android 中实现 JNI 的一种手段,通过 NDK,还可以打包 C/C++ 动态库,并自动打包进 APK/AAR 中。

最简单的 NDK 项目

Android Studio 新建项目的时候可以选择各种各样的模板,选择 Native C++ 模板就可以创建一个简单的 NDK 项目。

在 app/src/main/cpp 下可以看到有 CMakeList.txt 和 native-lib.cpp。
native-lib.cpp 里面是原生代码。
CMakeList.txt 是 CMake 构建脚本,用于把原生代码构建入库。

CMakeList.txt

# 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_minimum_required(VERSION 3.10.2)

# Declares and names the project.

project("myndk")

# 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.
        myndk

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        native-lib.cpp)

# 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.
        myndk

        # Links the target library to the log library
        # included in the NDK.
        $log-lib)

CMakeList 的具体解释可以见注释部分。

native-lib.cpp

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_teletian_sample_myndk_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) 
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());

一个简单的 C++ 方法,返回一个 Hello from C++ 的字符串。

  • 参数 JNIEnv* env:JNI 所有的接口函数都是通过这个指针调用的。
  • 参数 object:如果 Java 中此方法是实例方法,那么这边就是 Java 实例,如果是类方法,那么就是 Java 类。

这边还导入了一个头文件 jni.h,jni.h 中定义了 JNI 的数据类型、数据结构、接口函数、回调函数以及常量等等。

MainActivity.java

public class MainActivity extends AppCompatActivity 

    // Used to load the 'myndk' library on application startup.
    static 
        System.loadLibrary("myndk");
    

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // Example of a call to a native method
        TextView tv = binding.sampleText;
        tv.setText(stringFromJNI());
    

    /**
     * A native method that is implemented by the 'myndk' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

Java 中定义和 Java_com_teletian_sample_myndk_MainActivity_stringFromJNI 相对应的方法 stringFromJNI。
在使用之前,需要提前加载 CMakeList 中定义的 myndk 动态库。

app 下的 build.gradle 文件设置如下:

android 

    defaultConfig 

        externalNativeBuild 
            cmake 
                // 支持 c++11
                cppFlags '-std=c++11'
                // 需要运行的 CPU 类型
                abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
            
        
    
    
    // 指定 CMake 文件路径和版本 
    externalNativeBuild 
        cmake 
            path file('src/main/cpp/CMakeLists.txt')
            version '3.18.1'
        
    

以上是关于Android NDK- 认识 NDK的主要内容,如果未能解决你的问题,请参考以下文章

Android NDK 开发java传递数据到C

Android Studio NDK 入门教程--优雅的在C++中输出Logcat

Android NDK 开发Android NDK 下载 ( 下载指定历史版本 NDK | Android NDK r10e - 2015 年 5 月 )

android开发,怎么使用ndk编译成.so文件

android ndk是啥

如何改变ndk android