WEB开发网
开发学院手机开发Android 开发 Android JNI开发入门之一 阅读

Android JNI开发入门之一

 2010-12-18 08:04:01 来源:WEB开发网   
核心提示:{void *venv;LOGI("JNI_OnLoad!");if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {LOGE("ERROR: GetEnv failed");return -1;

{

void *venv;

LOGI("JNI_OnLoad!");

if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {

LOGE("ERROR: GetEnv failed");

return -1;

}

return JNI_VERSION_1_4;

}

请注意Java_com_simon_HelloWorld_printJNI函数的名字,这个名字是符合JNI规范的,Java_开头,后面 紧跟着调用他类名(包含包名和类名,com_simon_HelloWorld),然后才是接口的名字printJNI。这样java虚拟机就可以在 com.simon.HelloWorld类调用printJNI接口的时候自动找到这个C实现的Native函数调用。你可能注意到这个名字非常的长, 作为一个函数名它非常有可能不是一个好的选择。JNI API允许你提供一个函数映射表,注册给Jave虚拟机,这样Java虚拟机就可以用函数映射表来调用相应的函数,就可以不必通过函数名来查找需要调用的 函数了。这样你的函数名也可以随便定义了(可以定义最能表现函数功能的函数名),这个将会在helloworld共享库的C++实现中演示。但是 Android系统中,还是推荐用JNI标准的函数名定义的。

JNI_OnLoad函数JNI规范定义的,当共享库第一次被加载的时候会被回调,这个函数里面可以进行一些初始化工作,比如注册函数映射表,缓存一些变量等,最后返回当前环境所支持的JNI环境。本例只是简单的返回当前JNI环境。

注意网上很多例子都说可以不实现JNI_OnLoad,我发现如果不是实现的话,printJNI只可以返回整型类型的值,如果返回其他类型的 值都会崩溃。并且GetEnv的调用也是必须的,否则也是崩溃,但是GetEnv的返回值我并没有用到,这些地方使我非常迷惑,期待达人解惑。

接下来编写Android.mk文件,创建之,并输入:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=com_simon_Helloworld.c

LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)

LOCAL_MODULE := libhelloworld

LOCAL_SHARED_LIBRARIES := libutils

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)

这里面有几个标签需要说明:

1、LOCAL_C_INCLUDES说明包含的头文件,这里需要包含JNI的头文件。

2、LOCAL_MODULE当前模块的名称

3、LOCAL_SHARED_LIBRARIES当前模块需要依赖的共享库,因为在hellowold中我们调用Android打印系统输出到logger,所以我们必须要依赖libutils库。

4、LOCAL_PRELINK_MODULE指明该模块是否被启动就加载,可以参考《动态库优化——Prelink(预连接)技术》。我们的helloworld库不需要prelink,所以置为false。

编译这个模块,根据你的环境不同,选择不同的编译途径。然后安装apk,然后运行他们,通过logcat工具将会看到相应的输出。

上一页  1 2 3 

Tags:Android JNI 开发

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接