Java
package com.jni.api;
public class ApiNative {
static { System.loadLibrary("jni_api"); }
private final static ApiNative apiNative = new ApiNative();
public static ApiNative getInstance(){
return apiNative;
}
public native int init();
private void onJniNoticeA(float[] f1, float[] f2){
}
private void onJniNoticeB(int id, boolean isHigh){
}
private void onJniNoticeC(String serial){
}
public native int getInput(int id);
public native int setOutput(int id, boolean isHigh);
public native String getSerial();
}
JNI 被调用
#include <memory>
#include <fcntl.h>
#include <string.h>
#include <mutex>
#include "jni.h"
#include<android/log.h>
#define LOG_TAG "JNI-API"
#define ALOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args)
#define ALOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##args)
#define ALOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt, ##args)
JavaVM *jvm = nullptr;
jobject jobj = nullptr;
std::mutex mMutexMethod;
static jmethodID reqCall(JNIEnv **env, const char *name, const char *args)
{
JNIEnv *jniEnv = nullptr;
jclass javaClass = nullptr;
jmethodID javaCallback = nullptr;
mMutexMethod.lock();
if(jvm->AttachCurrentThread(&jniEnv, nullptr) != JNI_OK || nullptr == jniEnv) {
ALOGE("Couldn't attach thread");
mMutexMethod.unlock();
return nullptr;
}
javaClass = jniEnv->GetObjectClass(jobj);
if(nullptr == javaClass){
ALOGE("GetObjectClass failed...\n");
jvm->DetachCurrentThread();
mMutexMethod.unlock();
return nullptr;
}
javaCallback = jniEnv->GetMethodID(javaClass, name, args);
if(nullptr == javaCallback){
ALOGE("find onJniSwitchInputNotice failed...\n");
jvm->DetachCurrentThread();
mMutexMethod.unlock();
return nullptr;
}
*env = jniEnv;
return javaCallback;
}
static void resCall()
{
jvm->DetachCurrentThread();
mMutexMethod.unlock();
}
static jint init(JNIEnv *env, jobject object)
{
env->GetJavaVM(&jvm);
jobj = env->NewGlobalRef(object);
return 0;
}
static jint getInput(JNIEnv *env, jobject object, jint id)
{
return 0;
}
static jint setOutput(JNIEnv *env, jobject object, jint id, jboolean isHigh)
{
return 0;
}
static jstring getSerial(JNIEnv *env, jobject object)
{
char serial[32] = {"123456789"};
return env->NewStringUTF(serial);
}
static JNINativeMethod methods[] ={
{"init", "()I", (void *)init},
{"getInput", "(I)I", (void *)getInput},
{"setOutput", "(IZ)I", (void *)setOutput},
{"getSerial", "()Ljava/lang/String;", (void *)getSerial},
};
jint JNI_OnLoad(JavaVM * vm, void * reserved)
{
JNIEnv *env = NULL;
jclass myclz = NULL;
reserved = reserved;
if(vm->GetEnv((void * * )&env, JNI_VERSION_1_4)){
ALOGE("version error, not 1.4......\n");
return -1;
}
if((myclz = env->FindClass("com/jni/api/ApiNative")) == NULL){
ALOGE("find class \"com/jni/api/ApiNative\" failed......\n");
return -1;
}
if(env->RegisterNatives(myclz, methods, sizeof(methods)/sizeof(methods[0])) < 0){
ALOGE("register natives failed......\n");
return -1;
}
return JNI_VERSION_1_4;
}
Jni 回调
void onJniCallNoticeA(int i0[], float f1[], float f2[], unsigned int count)
{
JNIEnv *env = nullptr;
jmethodID javaCallback = nullptr;
if((javaCallback = reqCall(&env, "onJniNoticeA", "([F[F)V"))){
jfloatArray jf1 = env->NewFloatArray(chcnt);
env->SetFloatArrayRegion(jf1, 0, count, f1);
jfloatArray jf2 = env->NewFloatArray(chcnt);
env->SetFloatArrayRegion(jf2, 0, count, f2);
env->CallVoidMethod(jobj, javaCallback, jf1, jf2);
resCall();
}
return ;
}
void onJniCallNoticeB(int id, bool isHigh)
{
JNIEnv *env;
jmethodID javaCallback;
if((javaCallback = reqCall(&env, "onJniNoticeB", "(IZ)V"))){
env->CallVoidMethod(jobj, javaCallback, id, isHigh);
resCall();
}
return ;
}
void onJniCallNoticeC(const char *serial)
{
JNIEnv *env = nullptr;
char _serial[32] = {0};
jmethodID javaCallback = nullptr;
snprintf(_serial, sizeof(_serial), "%s", serial);
if((javaCallback = reqCall(&env, "onJniNoticeC", "(Ljava/lang/String;)V"))){
env->CallVoidMethod(jobj, javaCallback, env->NewStringUTF(_serial));
resCall();
}
return ;
}