美文网首页Android
Android NDK(一)- 认识 NDK

Android NDK(一)- 认识 NDK

作者: teletian | 来源:发表于2022-06-18 13:42 被阅读0次

    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

        本文链接:https://www.haomeiwen.com/subject/kxdhhrtx.html