多一分钟学习,早一秒钟提高

VC++、C++、Socket、DirectUI、wxWidgets、Cocos2d-x、CocosCreator、Unity3D、UE4、ThinkPHP
posts - 32, comments - 12, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Android NDK 开发教程三:Hello JNI 示例

Posted on 2013-11-24 12:55 虚空骄阳 阅读(7183) 评论(0)  编辑 收藏 引用 所属分类: Android

Android NDK 开发包带有不少例子,一个简单的例子Hello-Jni ,介绍了如何使用Java调用C函数。

1. 可以使用Eclipse的import 将该项目添加到工作目录中.

该项目目录结构如下:

├── AndroidManifest.xml
├── default.properties
├── hellojni.txt
├── jni
│   ├── Android.mk
│   └── hello-jni.c

├── res
│   └── values
│       └── strings.xml
├── src
│   └── com
│       └── example
│           └── hellojni
│               └── HelloJni.java
└── tests
├── AndroidManifest.xml
├── default.properties
└── src
└── com
└── example
└── HelloJni
└── HelloJniTest.java

上面列出使用NDK开发项目的基本的目录结构,C代码一般放在jni目录下。

2.  编译Native Code

i) 在命令行(Windows 环境下使用Cygwin的命令行) ,将当前目录改动到 <ndk-root>/samples/hello-jni

ii) 生成build.xml

android update project -p . -s  (注:Windows下可能需要  使用android.bat )

iii) 编译C代码

cd <ndk-root>/samples/hello-jni

<ndk_root>/ndk-build

3. 下面就可以使用Eclipse 编译运行 Hello Jni.

编写NDK的一般步骤,

1. 参考Hello-Jni ,修改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)

2.  定义Native函数,如HelloJni 中

public native String  stringFromJNI();

3. 在Eclipse中编译该项目,注意此时,你无需定义对于的Native文件中C函数,因为手工定义对于的C函数很容易出错,可以借助javah 工具来完成(包括在JDK中)。

4. 使用Javah 生成对应C函数定义

在命令行下  运行 javah com.example.hellojni.HelloJni

其中com.example.hellojni 为包名,注意运行Javah 的当前目录 为 <ndk>/examples/hello-jni/bin/classes (你也可以使用javah 的选项来指定classpath).

正确运行好,Javah产生 com_example_hellojni_HelloJni.h

定义如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_hellojni_HelloJni */

#ifndef _Included_com_example_hellojni_HelloJni
#define _Included_com_example_hellojni_HelloJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_hellojni_HelloJni
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI
(JNIEnv *, jobject);

/*
* Class: com_example_hellojni_HelloJni
* Method: unimplementedStringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_unimplementedStringFromJNI
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

从中可以找到native 方法对应的C函数定义,Java_com_example_hellojni_HelloJni_stringFromJNI

5. 定义对应的C函数,如Hello-jni 中定义

#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:
*
* apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
*/
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from JNI !");
}

6. 下面就可以使用ndk-build编译C代码,编译成功后会在libs 目录下生成libhello-jni.so

7. 在Java代码中调入编译好的C动态库

static {
  System.loadLibrary("hello-jni");
}

8. 编译运行,为了测试你的NDK例子的确成功运行,可以对Java_com_example_hellojni_HelloJni_stringFromJNI ,做点小改动 返回 “Hello world from JNI1 !。 注意要Clean Project,否则Eclipse可能不会重编译。


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理