Обучение Android JNI и NDK (1): обучение NDK

Обзор

Если вы хотите изучить JNI и NDK, вы должны сначала знать, что такое JNI и NDK и что они делают, чтобы вы могли лучше изучить и понять JNI и NDK. Эта статья в основном используется в качестве учебной заметки на случай, если вы забудете ее в будущее.

Введение в JNI

Определение: JNI - это Java Native Interfaceлокальный интерфейс Java.

Роль: разрешить Java взаимодействовать с другими типами языков (такими как C и C ++).

Примечание: JNI принадлежит java и не имеет ничего общего с android.

Введение в NDK

Определения: NDK Это Native Development Kitандроид из комплекта разработчика.

Функция: быстрая разработка динамической библиотеки C / C ++ и автоматическая упаковка файлов и приложений в APK.

Примечание: NDK принадлежит android и не имеет ничего общего с java.

Связь между JNI и NDK

 可以通过NDK工具  在Android中使用JNI与本地代码(C、C++)进行交互
 
 JNI是实现的目的,NDK是实现JNI的手段
 
 即在Android 的开发环境中(Android Studio)通过NDK实现JNI的功能

Используйте Android Studio для создания проекта NDK

Поскольку Android Studio 2.2 и выше имеет внутреннюю интеграцию NDK, его нужно настраивать только внутри Android Studio. В настоящее время я демонстрирую версию 3.5.3.

Вставьте описание изображения сюда
Вставьте описание изображения сюда
Вставьте описание изображения сюда

После этих трех шагов можно автоматически сгенерировать проект NDK.
Вставьте описание изображения сюда

По сравнению с обычными проектами эта папка больше, в ней содержится native-lib.cppкод C, C ++ и CMakelist.txtскрипты компиляции.

Давайте проанализируем этот проект

Основная деятельность

public class MainActivity extends AppCompatActivity {
    
    

    // Used to load the 'native-lib' library on application startup.
    static {
    
    
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

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

Сначала загрузите native-lib.so, затем вызовите stringFromJNIметод так и, наконец, отобразите значение, возвращаемое этим методом, TextViewна

Среди них native-lib.soимя этой библиотеки указано в CMklist.txt, который stringFromJNIявляется java- nativeметодом, а его реальная реализация находится native-lib.cppв

native-lib.cpp

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

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

Вышеупомянутая public native String stringFromJNI()реализация здесь, поэтому как определить, какому методу в Java соответствует собственный метод в C, вот статическая регистрация, то есть Java包名类名_方法名форма, а затем продолжить говорить о других методах регистрации

Весь поток звонков

  • Gradle вызывает внешний скрипт сборки CMklist.txt
  • CMake native-lib.cppкомпилирует исходный файл C ++ в native-lib.soдинамическую библиотеку в соответствии с командами в скрипте и компилирует его в APK.
  • Сначала загрузите во время выполнения native-lib.so, затем вызовите stringFromJNIметод так и, наконец, отобразите значение, возвращаемое этим методом, TextViewна

Настройте Gradle для поддержки NDK

Давайте сначала посмотрим на градиент проекта, созданного выше

Вставьте описание изображения сюда

Внутри красного поля настроен NDK, который необходимо настроить externalNativeBuild {}для добавления в gradle и использования cmake {}для настройки

Мы видим, что в Gradle используются два места: externalNativeBuild {}одно defaultConfigвнутри, а другое defaultConfigснаружи.

  • В defaultConfigнаружной части externalNativeBuild {}блока кода cmakeразработаны CMakeList.txtпути
  • В defaultConfigкотором externalNativeBuild {}блок кода cmakeв основном предназначен для заполнения CMakeпараметров команды

Анализ файла CMakeLists.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.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.

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).
        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.
        native-lib

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

cmake_minimum_required (ВЕРСИЯ 3.4.1)

Установите минимальную версию CMake

add_library

Первый параметр: задает имя библиотеки.
Второй параметр: задает тип библиотеки, SHARE динамическая библиотека суффикс .so, статическая библиотека STATIC суффикс .a.
Третий параметр: относительный путь к исходному файлу.

Вы можете определить несколько библиотек, CMake создаст их, а Gradle автоматически поместит общие библиотеки в APK.

find_library

Найдите библиотеку NDK и сохраните путь к ней в переменной. Например, в этом примере найдите библиотеку журналов в NDK (библиотека журналов, поддерживающая Android) и сохраните переменную в переменной log-lib.

target_link_libraries

Свяжите библиотеку, свяжите указанную библиотеку, например, в приведенном выше примере, первый параметр: целевая библиотека, а второй параметр: свяжите целевую библиотеку с библиотекой журналов и включите ее в NDK.

Это самый простой CMakeLists.txt, на самом деле он может быть очень мощным, например, вы можете настраивать команды, искать файлы, устанавливать переменные и т. Д., Рекомендуется обратиться к руководству CMAKE

ссылка:

https://blog.csdn.net/carson_ho/article/details/73250163

https://blog.csdn.net/afei__/article/details/80897404

https://www.jianshu.com/p/b4431ac22ec2

рекомендация

отblog.csdn.net/qq_34760508/article/details/106478299
рекомендация