Android中JNI使用方法

JNI,即Java Native Interface

参考JNI规范

Android Studio集成了NDK开发工具用于JNI开发,环境配置参考NDK配置及基本语法


Java类中声明本地方法

public native String stringFromJNI();

生成.h头文件

  • 进入java源码根目录,如MyNative\app\src\main\java
  • 对.java文件使用javah命令,如:
 javah demo.mynative.MainActivity

查看Java类中字段和方法的签名

  • 进入Java类所在目录,如MyNative\app\build\intermediates\classes\debug\demo\mynative
  • 对.class文件使用javap命令,如:
javap -p -s MainActivity.class

.cpp文件中实现本地方法

#include <jni.h>
#include <string>
#include <android/log.h>

extern "C"

#define LOG_TAG "native-lib"

JNIEXPORT jstring JNICALL Java_whoisblue_mynative_MainActivity_stringFromJNI(JNIEnv *env, jobject obj) {
    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "stringFromJNI");
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}


本地代码调用Java方法和字段

Java方法如:

    public int count = 0;

    public boolean onNativeCalled(int i) {
        Toast.makeText(this, "onNativeCalled " + i, Toast.LENGTH_SHORT).show();
        return true;
    }

本地代码如:

#include <jni.h>
#include <string>
#include <android/log.h>

extern "C"

#define LOG_TAG "native-lib"

JNIEXPORT jstring JNICALL Java_whoisblue_mynative_MainActivity_stringFromJNI(JNIEnv *env, jobject obj) {
    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "stringFromJNI");
    jclass cls = env->GetObjectClass(obj);
    
    jfieldID countId = env->GetFieldID(cls, "count", "I");
    env->SetIntField(obj, countId, 123);
    jint count = env->GetIntField(obj, countId);
    
    jmethodID methodId = env->GetMethodID(cls, "onNativeCalled", "(I)Z");
    env->CallBooleanMethod(obj, methodId, count);
    
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

动态注册本地方法

区别于上文的静态注册方式,即本地方法名遵循“Java_包名_类名_方法名”的格式以对应Java类中声明的方法。
另一种注册方式可通过JNI_OnLoad方法对本地方法名进行注册,本地方法名可自由格式。

Java类中声明本地方法:

public native int intFromJNI();

.cpp文件中实现方法,并动态注册:

#include <jni.h>
#include <string>
#include <android/log.h>

extern "C"

#define LOG_TAG "native-lib"

static jint JNICALL getInt(JNIEnv *env, jobject obj) {
    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "getInt");
    return 123456;
}

static const JNINativeMethod gMethods[] = {
        {"intFromJNI", "()I", (jint*)getInt}
};

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "JNI_OnLoad");
    JNIEnv* env;
    if(vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }

    if(env->RegisterNatives(env->FindClass("whoisblue/mynative/MainActivity"), gMethods, sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
        env->FatalError("RegisterNatives failed");
    }

    return JNI_VERSION_1_6;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值