Android JNI开发

概述

在开发framework的时候有时会遇到需要自己开发JNI,以便使Java能够调用自己底层开发的库。网上的文章一般都是介绍如何通过命名规则及javah,使jni层函数与java层函数自动建立链接(Java虚拟机通过命名规则建立),本文将讲解如何动态注册jni函数。

依赖库及头文件

先贴出Android.mk的代码

 1 LOCAL_PATH :=$(call my-dir)
 2 include $(CLEAR_VARS)
 3
 4 LOCAL_SRC_FILES := kiki_jni.cpp  5                    kiki_local.cpp  6
 7 LOCAL_SHARED_LIBRARIES := libandroid_runtime  8                        libnativehelper  9                        liblog 10
11 #dependence
12 LOCAL_REQUIRED_MODULES := 13
14 LOCAL_C_INCLUDES += $(JNI_H_INCLUDE) 15
16 #add micro define
17 LOCAL_CFLAGS += 18
19 LOCAL_MODULE := liblearnjni_jni
20
21 include $(BUILD_SHARED_LIBRARY)

LOCAL_SHARED_LIBRARIES:需要的共享库,在android中我们用刀libandroid_runtime及libnativehelper两个。

LOCAL_C_INCLUDES:需要的头文件包含,写$(JNI_H_INCLUDE)即可。

在Android的JNI架构中,一般会有一个JNI的cpp文件用于沟通上层Java与底层Cpp,具体的业务逻辑实现会放在底层Cpp的另一个文件中,因此这里用kiki_jni.cpp模拟JNI文件桥,kiki_local.cpp模拟实际实现逻辑的文件。

实际使用的头文件主要有:

#include <jni.h>
#include <JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"

JNI注册流程

JNI注册流程其实很简单,主要分为三个步骤:

1.实现JNI本地函数

2.通过JNINativeMethod机构体将Java函数与本地函数一一关联,实现映射表

3.调用AndroidRuntime::registerNativeMethods方法注册函数映射表

那么什么时候注册函数映射表呢?一般实现在jint JNI_OnLoad(JavaVM* vm, void* reserved)函数中。这个函数会在动态库被加载后第一时间执行,因此一般会在里面做一些初始化操作。具体代码如下:

 1 using namespace android;
 2
 3 static const char* const kLearnJni = "android/kiki/LearnJni";
 4
 5 static jint
 6 android_kiki_LearnJni_helloJni(JNIEnv *env, jobject thiz, jstring ip, jint port) {
 7     return getMagicNum();
 8 }
 9
10 static JNINativeMethod gMethods[] = {
11     {
12         "helloJni",
13         "(Ljava/lang/String;I)I",
14         (void *)android_kiki_LearnJni_helloJni
15     },
16 };
17
18 int register_android_kiki_LearnJni(JNIEnv *env) {
19     return AndroidRuntime::registerNativeMethods(env, kLearnJni, gMethods, NELEM(gMethods));
20 }
21
22 jint JNI_OnLoad(JavaVM* vm, void* reserved) {
23     JNIEnv *env = NULL;
24     jint res = -1;
25
26     if(vm -> GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
27         ALOGE("ERROR: Get java env failed");
28         goto bail;
29     }
30
31     if(register_android_kiki_LearnJni(env) <= 0) {
32         ALOGE("ERROR: LearnJni native registration failed");
33         goto bail;
34
35     }
36
37     res = JNI_VERSION_1_4;
38     ALOGD("JNI library onload success");
39
40 bail:
41     return res;
42 }

其他信息

每个Java进程有一个JavaVM,每个执行线程有一个JNIEnv,可以通过JavaVM获取当前JNIEnv。JNIEnv的本质就是提供出来的JNI操作Java对象的方法和成员变量的API接口类。JNIEnv通过getMethod及get<Type>Field方法获得Java对象的方法及成员变量,通过对应的call<Type>Method方法及set<Type>Field方法操作他们。

Java函数在JNI中签名对应如下:

比较特殊的就是boolean转为Z,long转为J。

时间: 2024-10-24 10:31:52

Android JNI开发的相关文章

Android jni开发有哪些常见的错误

我们在Android jni开发中,特别是对于刚入门学习Android jni开发的同学来说,往往会遇到很多错误,这里总结了我们经常遇见的错误.这些错误,你是否经常遇到. 错误1:java.lang.UnsatisfiedLinkError: Native method not found: 本地方法没有找到 1.本地函数名写错 2.忘记加载.so文件 没有调用System.loadlibrary 错误2:findLibrary returned null 1.System.loadLibrar

Android JNI开发提高篇

有关JNI的开发技术,我们继续围绕Android平台进行,JNI可以支持C或C++,从目前为止我们写过的JNI代码均为C实现的,即文件名为.C而C++的和这些有什么不同呢? Android平台上的JNI一般使用C还是C++编写呢? Android平台在中间层和大部分的类库的底层使用了C++的开发方式,后缀为.cpp,比如Android Framework.OpenCore.Webkit.SQLite等等.使用C++好处就是可以使用很多库但目前Android不支持STL,我们知道C表示字符串都是字

Android JNI开发生成.h头文件问题

在JNI开发中,首先要将建立的anroid类编译成.h文件,编译用到命令javah,由于第一次用,以前对java的编译过程也不怎么了解,这里讲一下: 通过DOS命令执行,(1)开始->运行->cmd->进入dos命令操作界面 在命令行中输入javah com.example.huiduhua2.ImageProc 通过输入javah 可以看到以下结果: 用法:javah [选项] <类> 其中 [选项] 包括: -help                 输出此帮助消息并退出

Android JNI开发生成.h头文件问题(转)

在JNI开发中,首先要将建立的anroid类编译成.h文件,编译用到命令javah,由于第一次用,以前对java的编译过程也不怎么了解,所以走了好多弯路,网络没有对这一步的详细介绍,这里讲一下: 通过DOS命令执行,(1)开始->运行->cmd->进入dos命令操作界面 在命令行中输入javah -classpath bin\classes -d jni com.sirc.jni.HelloWorld 通过输入javah 可以看到以下结果:用法:javah [选项] <类>

Android jni开发资料--NDK环境搭建

谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK.而在NDKr7开始,Google的Windows版的NDK提供了一个ndk-build.cmd的脚本,这样,就可以直接利用这个脚本编译,而不需要使用Cygwin了.只需要为Eclipse Android工程添加一个Builders,而为Eclipse配置的builder,其实就是在执行Cygwin,然后传递ndk-build作为参数,这样就能让Eclipse自

史上最易懂的Android jni开发资料--NDK环境搭建

谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK.而在NDKr7开始,Google的Windows版的NDK提供了一个ndk-build.cmd的脚本,这样,就可以直接利用这个脚本编译,而不需要使用Cygwin了.只需要为Eclipse Android工程添加一个Builders,而为Eclipse配置的builder,其实就是在执行Cygwin,然后传递ndk-build作为参数,这样就能让Eclipse自

Android JNI 开发 Demo by NDK (native develop kit)

最近终于有了一些空闲时间,所以想着把之前的Android相关的项目整理一下,前几天整理了Android OCR 的项目, 今天就干脆再整理一下 NDK JNI调用. 关于Android 中通过JNI进行本地调用的配置与开发,已经在链接 http://blog.csdn.net/watkinsong/article/details/9849973 中给出了非常详细的说明. 请仔细阅读. 同时,关于Android 作OCR的说明,也已经 在 http://blog.csdn.net/watkinso

Eclipse下的Android JNI 开发

1 创建Android工程 首先建立一个名为AndroidJniTest的Android工程,包名默认为com.example.androidjnitest,src目录下自动创建MainActivity.java. 2 设计JNI接口 创建新的文件包com.example.jni,并在改包下新建一个TestJNI.java的类. 打开TestJNI.java,我们将在这个文件里创建一个JNI接口类,该Java类提供一个加法运算的接口: public class TestJNI { public

Android Jni开发环境搭建

分几个步骤: 1. 安装cygwin 2. 配置NDK环境变量 3. 用NDK来编译程序            <---  到这里若生成了 *.so 文件,那么 NDK 开发环境就配好了 4. 1. 安装cygwin 下载包 cygwin2.738.zip   http://dl8.cr173.com/soft1/cygwin2.738.zip 注意安装 cygwin2.738 时候,注意的点,参考: http://blog.csdn.net/zhangrongde/article/detail