JNI方法的声明
import java.util.concurrent.atomic.AtomicBoolean;
public class FaceDtr {
private static final String TAG = "FaceDtr";
private static final String LIBRARY = "facedetection";
private static boolean isLoaded;
static {
if (!isLoaded) {
System.loadLibrary(LIBRARY);
isLoaded = true;
}
}
private static FaceDtr mFaceDtr = new FaceDtr();
private volatile AtomicBoolean mIsInitFaceDtrSuccess = new AtomicBoolean(false);
private FaceDtr() {
}
private static final native int nativeSendStream(byte[] buffer, int timeout);
}
- 创建_onload.h头文件
声明JNI_Onload(JavaVM *vm,void*reserved)方法。如下:
#ifndef ONLOAD_H_
#define ONLOAD_H_
#pragma interface
#include
#ifdef __cplusplus
extern "C" {
#endif
jint JNI_OnLoad(JavaVM *vm, void *reserved);
#ifdef __cplusplus
}
#endif
#endif
- 创建_onload.cpp文件
导入_onload.h头文件,实现JNI_Onload方法
#include "_onload.h"
#define LOCAL_DEBUG 0
extern int register_libFaceDtr(JNIEnv *env);
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
#if LOCAL_DEBUG
LOGD("JNI_OnLoad");
#endif
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
int result = register_libFaceDtr(env);
setVM(vm);
#if LOCAL_DEBUG
LOGD("JNI_OnLoad:finshed:result=%d", result);
#endif
return JNI_VERSION_1_6;
}
- 创建与FaceDtr中native方法对应的c/cpp文件face_dtr_jni.cpp。文件内容如下:
#include
#include
__attribute__((section (".mytext"))) static static int
nativeSendStream(JNIEnv *env, jobject thiz, jbyteArray byteArray, int timeout) {
if (mFaceDtr == NULL || mFaceDtr->mFaceDtrDev == NULL) {
LOGE("facedtr not init");
return -1;
}
if (byteArray == NULL) {
LOGE("Byte array is null");
return -1;
}
jsize length = env->GetArrayLength(byteArray);
if (length == 0) {
LOGE("Byte array is empty");
return -1;
}
jbyte *jbuffer = env->GetByteArrayElements(byteArray, NULL);
int len = 0;
int result = libusb_bulk_transfer(mFaceDtr->mFaceDtrDev->handle,
mFaceDtr->mFaceDtrDev->bulk_endpoint_out,
(unsigned char *) jbuffer, length,
&len,
timeout);
if (jbuffer != NULL) {
env->ReleaseByteArrayElements(byteArray, jbuffer, JNI_ABORT);
env->DeleteLocalRef(byteArray);
}
env->DeleteLocalRef(byteArray);
if (result != LIBUSB_SUCCESS) {
len = -1;
}
return len;
}
static JNINativeMethod methods[] = {
{"nativeSendStream", "([BI)I", (void *) nativeSendStream},
};
jint registerNativeMethods(JNIEnv *env, const char *class_name, JNINativeMethod *methods,
int num_methods) {
int result = 0;
jclass clazz = env->FindClass(class_name);
if (LIKELY(clazz)) {
int result = env->RegisterNatives(clazz, methods, num_methods);
if (UNLIKELY(result < 0)) {
LOGE("registerNativeMethods failed(class=%s)", class_name);
}
} else {
LOGE("registerNativeMethods: class'%s' not found", class_name);
}
return result;
}
int register_libFaceDtr(JNIEnv *env) {
LOGV("register_libfacedtr:");
if (registerNativeMethods(env,
"com/xxx/xx/FaceDtr",
methods, NUM_ARRAY_ELEMENTS(methods)) < 0) {
return -1;
}
return 0;
}
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/ \
$(LOCAL_PATH)/../ \
LOCAL_MODULE := facedetection
LOCAL_CFLAGS := -fvisibility=hidden
LOCAL_LDLIBS += -llog
LOCAL_SRC_FILES := \
_onload.cpp \
face_dtr_jni.cpp \
include $(BUILD_SHARED_LIBRARY)
- 在build.gradle 目录中声明ndk编译支持的版本
android{
···
defaultConfig {
minSdkVersion versionMinTarget
targetSdkVersion versionTarget
externalNativeBuild {
ndkBuild {
arguments "NDK_APPLICATION_MK:=src/main/jni/Application.mk"
cFlags "-DTEST_C_FLAG1", "-DTEST_C_FLAG2"
cppFlags "-DTEST_CPP_FLAG2", "-DTEST_CPP_FLAG2"
abiFilters "armeabi", "x86" ,"arm64-v8a"
}
}
}
externalNativeBuild {
ndkBuild {
path 'src/main/jni/Android.mk'
}
}
}
···