Android Jni 例子 Hello JNI,ndk

1.Android JNI介绍

Jni(Java Native Interface)是sun提供的java与系统中的原生方法交互的技术(在windows\linux系统中,实现java与native method互调)。目前只能由c/c++实现。

Android 底层是LInux,C,C++。有时候我们APK应用里也会调用C,C++的方法,虽然这种方式用的不多,我们还是要看下如何实现的。估计大公司JNI 会用的比较多,C,C++实现的东西容易跨平台,效率有时候会比JAVA高点。

2.拿官方的Hello-Jni做个说明吧

先说下JNI需要的平台和软件把(Linux 下)。虽然是简单的Hello-Jni,也让我弄了很久

1.Win7 + Java SDK 7.0 + Eclipse (这个比较简单,个人喜欢在WIndows下开发Android软件)

2.VMware 7 + Ubuntu 11 + Java SDK 6.0 + Android源码 + android-ndk-r7c + make-3.81

1.只有一台机子,就用虚拟机了,安装Ubuntu是容易的(需要准备至少35G空间),最后执行下StartX,和给Root 用户设置密码

2.安装Java SDK ,我是到官方网站下载个.jar文件,chomd+x后,执行下,再设置环境变量即可

3.下载Android源码,最好参考官方网站的指导,虽然是英文版的,但是是最新的,书上或网络上的大部分都过时了

4.编译Android源码,切换到放置Android源码的目录,make 执行下。

5.android-ndk-r7c也是到官方网站下的,不需要安装,解压到硬盘的特定位置即可(看了readme后再看install,才发现需要make-3.81+)

6.make-3.81 google 搜过来下,执行make -configure,make -check,make -install 即可。

7.切换到放置Android源码的目录, 执行 source ./build/envsetup.sh

3.先看下一个JNi 的源码目录结构吧

注意一下,我们这个项目中有一个特殊的文件夹jni 里面有 Android.mk,hello-jni.c两个文件

这两个文件的作用就是为了编译生成libs/armeabi/libhello-jni.so文件的。而java就是调用libhello-jni.so里的function的

4.开始编码

4.1/jni/Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)

有时候想给这几行加下注释,还是算了,hello-jni.c是要编译的目标文件,hello-jni是要生成.so文件的名称,会自动加上lib,其他的就照抄吧。如果还需要打印log什么的,就需要加上LOCAL_LDLIBS += -llog等。

4.2/jni/hello-jni.c


#include <string.h>
#include <jni.h>

/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
*   /src/com/example/HelloJni/HelloJni.java
*/
jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from JNI !");
}

先解释下jstring, 我们需要在c,c++和java之间传递值,中间桥梁就是这些以j开头的类型,string对于jstring

Java类型本地类型描述
booleanjbooleanC/C++8位整型
bytejbyteC/C++带符号的8位整型
charjcharC/C++无符号的16位整型
shortjshortC/C++带符号的16位整型
intjintC/C++带符号的32位整型
longjlongC/C++带符号的64位整型e
floatjfloatC/C++32位浮点型
doublejdoubleC/C++64位浮点型
Objectjobject任何Java对象,或者没有对应java类型的对象
ClassjclassClass对象
Stringjstring字符串对象
Object[]jobjectArray任何对象的数组
boolean[]jbooleanArray布尔型数组
byte[]jbyteArray比特型数组
char[]jcharArray字符型数组
short[]jshortArray短整型数组
int[]jintArray整型数组
long[]jlongArray长整型数组
float[]jfloatArray浮点型数组
double[]jdoubleArray双浮点型数组

解释下那个长长的函数名称Java_com_example_hellojni_HelloJni_stringFromJNI,这个函数名称可以自己打,但是要遵循它的规律,前面是java包的名称,最后面才是我们定义的方法名称。

这个函数名称也可以用这样的方法生成(假设我们的java文件叫TestJni.java,项目名称hello-jni,包名称com.example.hellojni):

1.先运行Android项目,这样会生成 “hello-jni\bin\classes\com\example\hellojni\TestJni.class” 类文件

2.打开cmd,cd 到 “hello-jni\bin\classes“ 执行javah com.example.hellojni.TestJni,会在hello-jni\bin\classes\目录下生成 com_example_hellojni_TestJni.h文件。这里头就有函数名称和返回值,参数。只是没有具体实现的。

4.3 编译生成xx.so文件

jni文件下有了Android.mk 和hello-jni.c就可以编译libhello-jni.so文件了。

这里我也卡了很久,我知道有两种方法可以生成:

1.linux cd到jni文件夹下面,执行mm命令,如果编译没错的话,会在类似:out\target\product\kpt75_ics\system\lib下生成so文件,这种方法调试比较麻烦,每次都要到这里复制so文件到项目中。

2.安装好make-3.81后,cd到项目根目录,执行~/myandroid/android-nkd-r7c/ndk-build, 红色字前面的路径取决与你的nkd解压放的路径,也可以把前面长长的路径添加到环境变量中,假设环境变量的名称角$NDK 那么就执行$NDK/ndk-build即可。用这种方法编译生成so文件,会自动在项目下建立lib/armeabi/lib-hellojni.so 文件,这样方便调试。

其实比较有参考价值是官方google提供的jni例子:有关于Opengl,播放音乐等程序。可以在下载的ndk里面找到。

最后是project 下载 hello-jni

Tags:

146

4 Responses to Android Jni 例子 Hello JNI,ndk

  1. […] 文章源地址:http://www.waitingfy.com/?p=146 […]

  2. Wedding Dresses说道:

    Took me time to read all the comments, but I seriously enjoyed the write-up. It proved to be Very helpful to me and I am positive to all the commenters right here Its always good when you can not only be informed, but also entertained Im sure you had fun writing this article.

  3. New samsung说道:

    Perfectly pent written content, appreciate it for selective information. ��The bravest thing you can do when you are not brave is to profess courage and act accordingly.�� by Corra Harris.

Leave a Reply

Name and Email Address are required fields.
Your email will not be published or shared with third parties.