1,首先,在android根目录建立test 目录,在test目录下再建立test目录,进入
2,进入test目录后vim HelloWorld.java
点击(此处)折叠或打开
- HelloWorld.java:
- package test;
- public class HelloWorld
- {
- public static void main(String[] args)
- {
- System.loadLibrary("HelloWorld");
- printHello();
- }
- public static native final void printHello();
- }
3,退出test目录,键入命令:../jdk1.5.0_22/bin/javac test/HelloWorld.java,test目录下将生成HelloWorld.class
4,键入../jdk1.5.0_22/bin/javah -o test/Hello.h test.HelloWorld,test目录下将生成Hello.h
5,在test目录下创建HelloWorld.cpp文件
点击(此处)折叠或打开
- HelloWorld.cpp:
- #include "Hello.h"
- #include <cstdio>
- Void Java_test_HelloWorld_printHello(JNIEnv *, jclass)
- {
- printf("helloworld");
- }
6,退出test目录,键入 g++ test/HelloWorld.cpp -I ../jdk1.5.0_22/include/ -I ../jdk1.5.0_22/include/linux/ -fPIC -shared -o test/libHelloWorld.so, test目录下将会生成libHelloWorld.so
7,运行../jdk1.5.0_22/bin/java test.HelloWorld 屏幕上会打印出helloworld.
出错情况:
1,如果g++ test/HelloWorld.cpp -I ../jdk1.5.0_22/include/ -fPIC -shared -o test/libHelloWorld.so 虽然jni.h在../jdk1.5.0_22/include/,但是如果不加上这边的目录-I ../jdk1.5.0_22/include/linux/的话,还是会报一大堆错误的。
2,如果运行的时候../jdk1.5.0_22/bin/java test.HelloWorld有
java.lang.UnsatisfiedLinkError: no HelloWorld in library path
at java.lang.Runtime.loadLibrary(Runtime.java)
at java.lang.System.loadLibrary(System.java)
at HelloWorld.main(HelloWorld.java)
类似的错误,那么就是因为LD_LIBRARY_PATH没有设置正确,用
LD_LIBRARY_PATH=test
export LD_LIBRARY_PATH
在运行一下就可以了。
参考自:
http://java.sun.com/docs/books/jni/html/start.html
动态方式:
关于动态方式,java上层的调用和静态方式是相同的,关键是native层的调用有所不同,主要关键在于三个地方:
1, 定义调用的JNINativeMethod
2, 定义调用挂钩的函数
3, 实现JNI_OnLoad函数
JNI_OnLoad是java jni技术的一个实现,每次java层加载System.loadLibrary之后,自动会查找改库一个叫JNI_OnLoad的函数,动态注册的时候,cpp可以通过实现JNI_OnLoad而完成jni的动态注册。
1,建立dynamic文件夹,进入,把静态连接的HelloWorld.java拷贝进来,并且修改package test;为package dynamic;
2,建立HelloWorld.cpp
点击(此处)折叠或打开
- #include "jni.h"
- #include <cstdio>
- // java转到native层的对应函数
- static int android_print(JNIEnv * env, jclass clazz)
- {
- printf("helloworld");
- }
- // 结构体,分别是java层的函数名称,签名,对应的函数指针
- static JNINativeMethod gMethods[] =
- {
- {"printHello", "()V", (void*)android_print},
- };
- // JNI_OnLoad函数实现
- jint JNI_OnLoad(JavaVM* vm, void* reserved)
- {
-
- JNIEnv* env = NULL;
- jint result = -1;
-
- if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
- return -1;
- }
- //如果要注册,只需要2不,首先FindClass,然后RegisterNatives就可以了
- char className[20] = {"dynamic/HelloWorld"};
- jclass clazz = (env)->FindClass( (const char*)className);
- if((env)->RegisterNatives(clazz, gMethods, 1)< 0)
- {
- return -1;
- }
- //一定要返回版本号,否则会出错。
- result = JNI_VERSION_1_4;
-
- return result;
- }
然后编译一下:
编译java
../jdk1.5.0_22/bin/javac dynamic/HelloWorld.java
编译cpp生成.so
g++ dynamic/HelloWorld.cpp -I ../jdk1.5.0_22/include/ -I ../jdk1.5.0_22/include/linux/ -fPIC -shared -o dynamic /libHelloWorld.so, dynamic目录下将会生成libHelloWorld.so
设置LD_LIBRARY_PATH环境变脸
运行Java
../jdk1.5.0_22/bin/java dynamic.HelloWorld 屏幕上会打印出helloworld