android JNI的使用示例详解
来源:互联网 发布:mac电脑显示器分辨率 编辑:程序博客网 时间:2024/06/11 16:53
众所周知,android是使用java进行开发,但是在开发过程中可能会用到之前的c,c++代码,或者乳沟你想一套代码同时在iphone和android平台复用就会用到JNI啦。
JNI起的是一个桥梁的作用,可以转化java与c/c++的一些区别,比如数据类型等。之后我们将转换好的c代码生成动态链接库,供java调用。
下面以一个示例做说明,希望对刚接触的童鞋有所帮助。
1、安装NDK环境:这个可以参照我的前一篇文章“windows系统上安装与使用Android NDK r5”。这是一个童鞋写的,照着做就可以完全没有问题的安装好。
2、当你按照步骤1安装好环境后,比如安装在了D盘D:\android-ndk-r6,本文以下默认此路径,如果你的路径不同 做相应改变就好了。然后在D:\android-ndk-r6下新建apps文件夹,里面存放的就是你将来要搞的android jni 工程相关文件啦。
现在我在D:\android-ndk-r6\apps 下创建我的第一个工程目录Angry,注意这个Angry并不是你的android工程的根目录,在Angry下创建project文件,这下面存放的将是你的android工程。 以下是我的目录结构:
之所以这样是因为,大家可以看到在Angry下还有个Application.mk文件(下面讲这个文件的生成),这个文件里是我们将c/c++编译成动态链接库(.so)的时候需要使用到的配置信息。除这个文件外我们还会用到一个Android.mk文件,在下面会讲到。
3.好了,接下来就创建我们的android工程吧。创建Android工程,指定工程路径:D:\android-ndk-r6\apps\Angry\project,以下是我创建的工程:
创建好了之后就可以写我们的java接口了(相当于函数声明),真正的功能实现是要用c/c++实现的吆。你可以新建一个java文件,或者直接在你继承Activity的那个java中直接写,我是新建了一个Jni.java文件:
Jni.java中的代码如下:
package com.Angry;public class Jni {public native String getString ();}
注意接口要声明成native的吆。如果你不想单独放在一个文件中也可以直接放在MainAct.java中,将 public native String getString (); 放进去就好了。
4.生成头文件以及源文件:
将Jni.java复制到D:\android-ndk-r6\apps\Angry\project\bin下面,然后在D:\android-ndk-r6\apps\Angry\project\bin用“javac jni.java”编译生成Jni.class文件,将生成的Jni.class复制到 D:\android-ndk-r6\apps\Angry\project\bin\com\Angry下覆盖掉原先的Jni.class文件。
然后再在D:\android-ndk-r6\apps\Angry\project\bin下使用命令 "javah -jni com.Angry.Jni" 这是将会在bin下生成一个com_Angry_Jni.h的头文件,大家可以看一下我的生成:、
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_Angry_Jni */#ifndef _Included_com_Angry_Jni#define _Included_com_Angry_Jni#ifdef __cplusplusextern "C" {#endif/* * Class: com_Angry_Jni * Method: getString * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_Angry_Jni_getString (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
其实就是将我们原先Jni.java中的public native String getString ();函数声明形式做了些许改动,使之符合JNI规则。
之后我们要在D:\android-ndk-r6\apps\Angry\project下即Android工程下新建jni文件夹,将com_Angry_Jni.h文件放入其中。这个jni文件夹将是盛放我们c/c++源文件以及头文件和Android.mk文件的场所。
接下来就是实现我们的函数功能了:新建c/c++源文件:com_Angry_Jni.c(同样放在jni文件夹下):
#include <stdio.h>#include <stdlib.h>#include "com_Angry_Jni.h"JNIEXPORT jstring JNICALL Java_com_Angry_Jni_getString (JNIEnv *env, jobject thiz) { return (*env)->NewStringUTF(env, "I,M ANGRY");}
像我就只是单纯的实现了返回一字符串的功能,具体功能大家可以自己添加。程序中的jstring 等数据类型其实jni对c/c++的数据类型做了形式的改变,jstring 就是String。
现在功能都实现好了,我们可以将上面的c代码编译成so文件供java调用(因为android是基于linux的,而linux的动态链接库文件是以.so为后缀,windows以.dll为后缀)。
5、编译生成.so文件需要两个.mk文件,就是我们上面提到的Application.mk文件和Android.mk,在D:\android-ndk-r6\apps\Angry\project\jni下创建Android.mk,内容如下:
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := AngryLOCAL_SRC_FILES := com_Angry_Jni.cinclude $(BUILD_SHARED_LIBRARY)
LOCAL_PATH: 表示位于工程的根目录。
include $(CLEAR_VARS) 功能还不太清楚我。
LOCAL_MODULE := Angry 这个表明你的一个动态链接库的名字,所以你的链接库生成后会叫libAngry.so,libxxx.so是系统加的,xxx即此处的名字。
LOCAL_SRC_FILES := com_Angry_Jni.c 这是你要编译的源文件。
还有好多配置指令,有兴趣大家可以自己查。
然后再在D:\android-ndk-r6\apps\Angry 下创建Applicetion.mk文件:
APP_PROJECT_PATH := $(call my-dir)/projectAPP_MODULES := Angry
APP_MODULES := Angry 指明了你的应用模块。
6、到此为止,我们都把准备工作做好了,接下来生成.so文件:
启动cygwin,进入NDK根目录:D:\android-ndk-r6,运行命令:make APP=Angry 如果显示:
则表示.so生成并安装成功,你可以看到在 D:\android-ndk-r6\apps\Angry\project 下多了一个两层目录libs\armeabi\ 下面放着我们生成的libAngry.so。
7、到此为止,基本大功告成,下面我们验证一下c函数的功能能否实现:
在MainAct.java中实现如下简单代码:
package com.Angry;import android.app.Activity;import android.os.Bundle;import android.widget.TextView;public class MainAct extends Activity { private TextView tv; /** Called when the activity is first created. */ static { System.loadLibrary("Angry"); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Jni jni = new Jni(); tv = (TextView)findViewById(R.id.tv); tv.setText(jni.getString()); }}
运行下,看看效果:
已经正确调用了呀。大家试试吧!
- android JNI的使用示例详解
- android JNI 示例详解
- Android-JNI使用详解
- Android JNI 使用的数据结构JNINativeMethod详解 动态注册JNI
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- JavaScript_正则表达式小试牛刀-字符串的替换
- 使用Oracle SQL trace时需要注意的问题
- linux popen函数
- 【C语言】IO--文件操作要点
- Unknown symbol platform_device_put 问题
- android JNI的使用示例详解
- Delete of BizTalkServerIsolatedHost failed解决方法
- Activity的补充流程
- 动态注册数据库监听
- CSV 导出
- 接口测试结束后的小结
- servlet的定义及其生命周期
- jquery ajax webservice
- MAVEN项目标准目录结构