Android JNI开发入门之一
来源:互联网 发布:联合国工作 知乎 编辑:程序博客网 时间:2024/06/11 09:17
Android JNI开发入门之一
- 2010十二月07
- 作者:Simon_fu
- 目录: Android, Java, ...
- 评论: 1 条评论
交叉编译环境
Java编写的Android应用程序
package com.simon;import android.app.Activity;import android.os.Bundle;import android.util.Log;public class HelloWorld extends Activity { private static final String TAG = "HelloWorld"; static { System.loadLibrary("helloworld"); } private native String printJNI(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.d(TAG, "Activity call JNI: " + printJNI()); }}
C语言实现helloworld共享库
javah com.simon.HelloWorld
你将会得到,一个头文件com_simon_Helloworld.h,这里包含有printJNI接口的C/C++声明。这个声明肯定正确,如果你把printJNI接口声明写错了,HelloWorld将找不到printJNI接口,然后产生崩溃。
#include <jni.h>#define LOG_TAG "HelloWorld"#include <utils/Log.h>JNIEXPORT jstring JNICALL Java_com_simon_HelloWorld_printJNI(JNIEnv *env, jobject obj){ LOGI("Hello World From libhelloworld.so!"); return (*env)->NewStringUTF(env, "Hello World!");}jint JNI_OnLoad(JavaVM* vm, void* reserved){ 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函数调用。你可能注意到这个名字非常的长,作为一个函数名它非常有可能不是一个好的选择。JNIAPI允许你提供一个函数映射表,注册给Jave虚拟机,这样Java虚拟机就可以用函数映射表来调用相应的函数,就可以不必通过函数名来查找需要调用的函数了。这样你的函数名也可以随便定义了(可以定义最能表现函数功能的函数名),这个将会在helloworld共享库的C++实现中演示。但是Android系统中,还是推荐用JNI标准的函数名定义的。
注意网上很多例子都说可以不实现JNI_OnLoad,我发现如果不是实现的话,printJNI只可以返回整型类型的值,如果返回其他类型的值都会崩溃。并且GetEnv的调用也是必须的,否则也是崩溃,但是GetEnv的返回值我并没有用到,这些地方使我非常迷惑,期待达人解惑。
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=com_simon_Helloworld.cLOCAL_C_INCLUDES := $(JNI_H_INCLUDE)LOCAL_MODULE := libhelloworldLOCAL_SHARED_LIBRARIES := libutilsLOCAL_PRELINK_MODULE := falseinclude $(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。
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之二
- Android JNI开发入门之二
- android pad开发 基础入门之一
- Android JNI环境搭建及开发入门
- Android JNI开发入门
- Android JNI开发入门
- Android JNI开发入门
- Android project 的常用编译方法
- Android project 的常用编译方法
- 第一个驱动helloworld module加载i…
- 第一个驱动helloworld module加载i…
- Android JNI开发入门之一
- Android JNI开发入门之一
- Android JNI开发入门之二
- Android JNI开发入门之二
- Android HAL实践(一):Mini6410…
- Android HAL实践(一):Mini6410…
- 解决lib只读的问题
- 解决lib只读的问题
- 在x86的机器上编译使用Andorid
- 在x86的机器上编译使用Andorid