Динамическая регистрация Android JNI (Android Studio)

История должна начаться здесь - статическая регистрация

Без сравнения нет вреда. Статическая регистрация неоднократно подвергалась критике с момента ее появления. Громоздкий процесс (javah генерирует заголовочный файл), каждый раз при добавлении интерфейса шлак нужно х. Длинные названия функций, подробная идентификация. Эффективность работы низкая.При первом общении сложнее найти человека с соответствующей идентичностью в jni по детальной идентичности.Сравнивайте их по очереди.Если повезет,отношения устанавливаются после одного Если, скажем, если к концу все лилейники остынут. Когда трудно, когда пора сдаваться, пора мужчине выйти на сцену, динамическая прописка, да, это он. В JNI есть таблица сопоставления функций, которая зарегистрирована на виртуальной машине Java.Это любовь с первого взгляда, и связь настолько гладкая.

Динамическая регистрация, нарисуйте несколько кругов

Есть еще правила. Заранее создайте базу данных и немедленно общайтесь.

один. Введите метод JNI_OnLoad

После того как System.loadLibrary загружает динамическую библиотеку JNI, она вызывает функцию JNI_OnLoad для запуска динамической регистрации. Это место для регистрации.Вы не можете найти неправильное место.Если вы обратитесь в полицию, чтобы поймать вора, вы должны позвонить 119. Мне тоже очень грустно, но я ничего не могу сделать. Примечание. В одном .so может быть только один метод загрузки.

два. Изюминка метода RegisterNatives

В империи JNI я должен представить JNIEnv*, представителя JVM, который держит власть над жизнью и смертью в java.Указатель на переменную среды java представляет собой структуру, содержащую интерфейс JVM, который включает в себя необходимые для взаимодействовать с JVM и работать с объектами Java Функция. А RegisterNatives — всего лишь одна из пешек, регистратор. Но только через него можно войти в таблицу сопоставления функций. Карта функций? Не волнуйтесь, давайте не торопимся и шаг за шагом вырвем его сердце. В империи jni.h в описании есть такой абзац:

typedef struct { 
    const char* name; //Java中函数的名字
    const char* signature; //描述了函数的参数和返回值
    void* fnPtr; //函数指针,指向我们调用别人家c++的封装 JNI 函数方法
} JNINativeMethod; 

Это структура данных таблицы сопоставления функций.С добавлением комментариев вроде бы и объяснять нечего.Что касается утомительного разбора исходников,как используется эта структура? Кхе-кхе-кхе, вернемся к теме, изюминке RegisterNatives, это придворная эпическая драма, тщательная верстка, грандиозные сцены. Скажем так, есть только три актера, A, B и C, которые будут играть одну из главных ролей в финале истории, где либо ты умрешь, либо я умру. Этот отрывок записан в сценарии:

/**
 * 向JNI环境注册一个本地方法
 * @param clazz  包含本地方法的Java类
 * @param methods 本地方法描述数组
 * @param nMethods 本地方法个数
 * @return 成功返回0,否则注册失败
 */
jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods);

Неосознанно, оглядываясь назад, комментарий завершает анализ. Будьте проще, будьте проще в том, как вы говорите. Я, кто должен сотрудничать с вашим выступлением, закрываю глаза. Описание регистратора примерно такое же. Если у вас есть дополнительные потребности, пожалуйста, проведите собственное исследование.

три. Завершите метод JNI_OnUnload.

Тем, кто выходит потусоваться, рано или поздно придется расплачиваться, и огромной империи JNI однажды придет конец. Когда виртуальная машина выпустит компонент, она вызовет метод JNI_OnUnload.Все объекты, которыми она когда-то владела, например объекты, вернутся сюда на землю и превратятся в весеннюю грязь для защиты цветов. Конечно, вы также можете отказаться и оставить этот метод в стороне, тогда ядовитые грибы будут процветать в один прекрасный день, медленно и медленно, а затем бум. Оптимизация — это вариант для нас с вами.

Четыре. Моменты чудесного свидетеля

Должен сказать, в данный момент я очень взволнован. Цветы, почему вы такие красные? Вставьте код немного, с небольшими деталями:

static const char *jniClassName = "net/mapout/jni/JNILoader";
static JNINativeMethod methods[] = {
        {
   
   "sayHello", "()Ljava/lang/String;", (void*)jniSayHello},
};

static int registerNatives(JNIEnv* env) {
    jclass clazz = env->FindClass(jniClassName);
    if (clazz == NULL)
        return JNI_FALSE;

    jint methodSize = sizeof(methods) / sizeof(methods[0]);
    if ( env->RegisterNatives(clazz, methods, methodSize) < 0 )
        return JNI_FALSE;

    return JNI_TRUE;
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK)
        return JNI_ERR;

    //注册方法
    if (!registerNatives(env))
        return JNI_ERR;

    result = JNI_VERSION_1_6;
    return result;
}

JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
    JNIEnv *env = nullptr;
    jint ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
    if (ret != JNI_OK) {
        return ;
    }
    //回收二手女朋友,回收... 嘿嘿嘿
}

На первый взгляд, нам нужно поддерживать массив методов, а остальное копировать и вставлять. Для небольшого сравнения:

/**
 * 动态注册。命名简洁,清晰明了
 */
jstring jniSayHello(JNIEnv *env, jobject obj){
     return str2jstring( env, sayHello() );
}

/**
 * 静态注册。噗噗噗,一口老血喷涌而出
 */
JNIEXPORT jstring JNICALL Java_net_mapout_jni_JNILoader_sayHello
  (JNIEnv *env, jclass jclass){
    return str2jstring( env, sayHello() );
}

Еще одно замечание. Для кода нет комментария, который не может быть понятен. Если есть, используйте два комментария. Чтобы поговорить о деталях, функция здесь имеет 2 параметра, JNIEnv * был объяснен и jobject. Грубо говоря, если нативный метод не имеет статики, то он является экземпляром класса, а если он вооружен статикой, то он будет улучшен эволюцией и станет экземпляром объекта класса класса. Динамическая регистрация, вот что это такое, пора показать свою силу.

Схема структуры проекта динамической регистрации

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

отblog.csdn.net/youyi300200/article/details/72841441