Android JNI接口的使用示例

Android JNI接口的使用示例

yangtutu_jni.cpp

#include <jni.h>	//必须要的头文件

#include <stdio.h>  
#include <sys/time.h> 
#include <android/log.h>

//用来获取系统时间,精确到ms,可以测量程序运行时间
static long getCurrentTimeMs(void)
{
   struct timeval tv;
   gettimeofday(&tv,NULL);
   return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

//参数:int;返回值:bool
jboolean yangtutu_bool_int(JNIEnv *env, jobject obj, jint a)
{
	//int这种基础数据类型,可以直接获取到
	int b = a;	//int类型可以直接获取
	
	//这里可以把log打印到Android log里面
	__android_log_print(ANDROID_LOG_WARN, "yangtutu_jni", "b=%d", b);

	return 1;	//bool类型的值可以直接返回
}

//参数:byte[];返回值:int
jint yangtutu_int_byteArray(JNIEnv *env, jobject obj, jbyteArray buffer)
{
	int count;
	unsigned char *buffer_ptr;
	
	//数组这种引用类型数据,无法直接获取到
	//获取参数byte[]的数组指针,使用这个指针,可以直接操作java层的数组
	buffer_ptr = (unsigned char *)(env->GetByteArrayElements(buffer,0));
	//获取参数byte[]的数组长度
	count = (int)(env->GetArrayLength(buffer));

	//记录算法开始时间
	__android_log_print(ANDROID_LOG_ERROR, "yangtutu_jni", "time_start=%ld", getCurrentTimeMs());
	
	//将数组所有元素清零
	for(count -= 1; count >= 0; count--)
		buffer_ptr[count] = 0;

	//记录算法结束时间
	__android_log_print(ANDROID_LOG_ERROR, "yangtutu_jni", "time_end=%ld", getCurrentTimeMs());

	//释放数组指针和数组之间的引用
	env->ReleaseByteArrayElements(buffer,(jbyte *)buffer_ptr,0);

	return count;
}

//当java代码去加载这个jni文件的.so的时候,VM会去执行这个函数,注册native方法
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv* env = NULL;

	__android_log_print(ANDROID_LOG_WARN, "yangtutu_jni", "JNI_OnLoad!!");

    if(vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
	{
		__android_log_print(ANDROID_LOG_ERROR, "yangtutu_jni", "JNI_EVERSION!!");
        return JNI_EVERSION;
    }

	//java代码通过“YangTuTuJni”类声明native方法,供其他类或方法调用
    jclass myclass = env->FindClass("com/android/YangTuTuJni");
	if(myclass == NULL)
	{
		__android_log_print(ANDROID_LOG_ERROR, "yangtutu_jni", "FindClass Error!!");
        return JNI_ERR;
	}

	//这里就是上面两个函数,对应“YangTuTuJni”类里面声明的两个native方法
	const JNINativeMethod method[] = {
            {"native_bool_int","(I)Z",(void*)yangtutu_bool_int},
            {"native_int_byteArray","([B)I",(void*)yangtutu_int_byteArray}
    };

    if(env->RegisterNatives(myclass, method, 2) != JNI_OK)
	{
        __android_log_print(ANDROID_LOG_ERROR, "yangtutu_jni", "RegisterNatives Error!");
        return JNI_ERR;
    }

    return JNI_VERSION_1_6;
}

Android.mk

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
	yangtutu_jni.cpp

LOCAL_C_INCLUDES += \
	$(JNI_H_INCLUDE) \
	$(call include-path-for, bluedroid) \
	$(call include-path-for, libhardware)/hardware \
	$(call include-path-for, libhardware_legacy)/hardware_legacy

LOCAL_SHARED_LIBRARIES := \
	libnativehelper \
	liblog \
	libcutils \
	libutils \
	libhardware \
	libhardware_legacy

LOCAL_MODULE:= libyangtutu_jni

include $(BUILD_SHARED_LIBRARY)

YangTuTuJni.java

package com.android;

import java.io.FileDescriptor;
import java.io.IOException;
import android.util.Log;

public final class YangTuTuJni{

	private static final String TAG = "YangTuTuJni";

    static {
        try {
        	//这里加载jni的.so动态链接库,jni文件里面的“JNI_OnLoad”函数,在这个时候被执行!
            System.loadLibrary("yangtutu_jni");		
			Log.w(TAG, "loadLibrary ok !! ");
        } catch (UnsatisfiedLinkError e) {
			Log.e(TAG, "loadLibrary UnsatisfiedLinkError !! ");
            e.printStackTrace();
        } catch (Exception e) {
			Log.e(TAG, "loadLibrary Exception !! ");
            e.printStackTrace();
        }
    }

	//声明的和jni对应的native方法
	public static native boolean native_bool_int(int a);
	public static native int native_int_byteArray(byte[] buffer);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值