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 中定义
jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ) { return (*env)->NewStringUTF(env, "Hello from JNI1 !"); }
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可能不会重编译。