189 8069 5689

【Android】JNI静态与动态注册介绍-创新互联

【Android】JNI静态与动态注册介绍

JNI的两种注册机制:静态注册和动态注册

在来安等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站设计、做网站 网站设计制作定制网站建设,公司网站建设,企业网站建设,品牌网站制作,成都全网营销,外贸网站制作,来安网站建设费用合理。JNI介绍

JNI(Java Native Interface),即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C++机型交互.

方式:

  • 静态注册
  • 动态注册:需要提供Java中Native方法的方法签名和Native层中对应的实现函数。
静态注册

要求C/C++层的函数名符合某种特定的要求:包含Java中Native方法的目录信息和方法名。

Example

Java

package cn.com.codingce.ndkpractice;

public native String stringFromJNI();

C++

extern "C"
JNIEXPORT jstring JNICALL
Java_cn_com_codingce_ndkpractice_MainActivity_stringFromJNI(JNIEnv *env, jobject thiz) {std::string hello = "Hello from C++";
    //crashTest();

    return env->NewStringUTF(hello.c_str());
}

按照以上规则进行命名,在调用到Native的方法时,JVM会去查找是否存在对应函数名的函数,以此实现静态注册。

动态注册

动态注册相对于静态注册,优点是不再根据特定路径查找函数的实现,带来两个好处:

  • 没有了冗杂的函数名,适用于大型项目开发。
  • 由于不再根据Native函数查找对应的JNI层函数,所以首次调用速度比静态注册快。

开发者需要自行提供Java层和C/C++层中的映射关系。

一种可行的方法是基于JNI重载JNI_OnLoad(),在其中对函数进行动态注册。

Example

Java

package cn.com.codingce.ndkpractice.utils;

public static native void logInit(String logFilePath, String logName, int logfileLevel, int logScreenLevel);

C++

此步骤涉及到如何获取Java函数。

static JNINativeMethod nativeUtilsMethods[] = {{"logInit",  "(Ljava/lang/String;Ljava/lang/String;II)V", (void *) localLogInit},
        {"logJni",   "(ILjava/lang/String;)V",                    (void *) logJni},
        {"logClose", "()V",                                       (void *) logClose},
};

static void nativeLogUtilsRegisterNatives(JNIEnv *jniEnv) {if (jniEnv == nullptr) {return;
    }

    jclass clazz = nullptr;
    do {clazz = jniEnv->FindClass("cn/com/codingce/ndkpractice/utils/LogUtils");
        if (clazz == nullptr) {diagnosis_assert(!"FindClass LogUtils error!");
            break;
        }
        if (jniEnv->RegisterNatives(clazz, nativeUtilsMethods,
                                    std::extent::value) != 0) {diagnosis_assert(!"RegisterNatives error!");
            break;
        }
    } while (false);
    if (jniEnv->ExceptionCheck() == JNI_TRUE) {jniEnv->ExceptionClear();
    }
    if (clazz != nullptr) {jniEnv->DeleteLocalRef(clazz);
    }
}

重载JNI_OnLoad函数,并在其中调用nativeLogUtilsRegisterNatives函数

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {JNIEnv *jniEnv{nullptr};
    if (vm->GetEnv((void **) &jniEnv, JNI_VERSION_1_6) != JNI_OK) {diagnosis_assert(!"JNI version error!");
        return JNI_EVERSION;
    }

    nativeLogUtilsRegisterNatives(jniEnv);
    return JNI_VERSION_1_6;
}

更多内容:

Github:https://github.com/xzMhehe
Gitee:https://gitee.com/codingce

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


当前题目:【Android】JNI静态与动态注册介绍-创新互联
网站地址:http://cdxtjz.cn/article/jdeej.html

其他资讯