`
yzw2007
  • 浏览: 18601 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

JAVA JNI 编程进阶

    博客分类:
  • java
阅读更多
JNI一直以来都很少去关注,但却是我心中的一个结,最近这几天刚好手头有点时间,因此抽空看了一下这方面的东西,整理了一份文档,JNI技术的出现主要是基于三个方面的应用需求:

1. 解决性能问题
Java具有平台无关性,这使人们在开发企业级应用的时候总是把它作为主要候选方案之一,但是性能方面的因素又大大削弱了它的竞争力。为此,提高Java的性能就显得十分重要。Sun公司及Java的支持者们为提高Java的运行速度已经做出了许多努力,其中大多数集中在程序设计的方法和模式选择方面。由于算法和设计模式的优化是通用的,对Java有效的优化算法和设计模式,对其他编译语言也基本同样适用,因此不能从根本上改变Java程序与编译型语言在执行效率方面的差异。由此,于是人们开始引入JIT(Just In Time,及时编译)的概念。它的基本原理是:首先通过Java编译器把Java源代码编译成平台无关的二进制字节码。然后在Java程序真正执行之前,系统通过JIT编译器把Java的字节码编译为本地化机器码。最后,系统执行本地化机器码,节省了对字节码进行解释的时间。这样做的优点是大大提高了Java程序的性能,缩短了加载程序的时间;同时,由于编译的结果并不在程序运行间保存,因此也节约了存储空间。缺点是由于JIT编译器对所有的代码都想优化,因此同样也占用了很多时间。

动态优化技术是提高Java性能的另一个尝试。该技术试图通过把Java源程序直接编译成机器码,以充分利用Java动态编译和静态编译技术来提高Java的性能。该方法把输入的Java源码或字节码转换为经过高度优化的可执行代码和动态库 (Windows中的. dll文件或Unix中的. so文件)。该技术能大大提高程序的性能,但却破坏了Java的可移植性。
JNI(Java Native Interface, Java本地化方法)技术由此闪亮登场。因为采用JNI技术只是针对一些严重影响Java性能的代码段,该部分可能只占源程序的极少部分,所以几乎可以不考虑该部分代码在主流平台之间移植的工作量。同时,也不必过分担心类型匹配问题,我们完全可以控制代码不出现这种错误。此外,也不必担心安全控制问题,因为Java安全模型已扩展为允许非系统类加载和调用本地方法。根据Java规范,从JDK 1. 2开始,FindClass将设法找到与当前的本地方法关联的类加载器。如果平台相关代码属于一个系统类,则无需涉及任何类加载器; 否则,将调用适当的类加载器来加载和链接已命名的类。换句话说,如果在Java程序中直接调用C/C++语言产生的机器码,该部分代码的安全性就由Java虚拟机控制。

2. 解决本机平台接口调用问题
JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。

3. 嵌入式开发应用
“一次编程,到处使用”的Java软件概念原本就是针对网上嵌入式小设备提出的,几经周折,目前SUN公司已推出了J2ME(Java 2 P1atform Micro Edition)针对信息家电的Java版本,其技术日趋成熟,开始投入使用。SUN公司Java虚拟机(JVM)技术的有序开放,使得Java软件真正实现跨平台运行,即Java应用小程序能够在带有JVM的任何硬软件系统上执行。加上Java语言本身所具有的安全性、可靠性和可移植性等特点,对实现瘦身上网的信息家电等网络设备十分有利,同时对嵌入式设备特别是上网设备软件编程技术产生了很大的影响。也正是由于JNI解决了本机平台接口调用问题,于是JNI在嵌入式开发领域也是如火如荼。

不失直观性,我们首先写一个JNI小例子:

Java代码 
1. public class HelloJni {  
2.     public native void displayHelloJni();  
3.  
4.     static {  
5.         System.loadLibrary("helloJni");  
6.     }  
7.  
8.     public static void main(String[] args) {  
9.         //System.out.println(System.getProperty("java.library.path"));  
10.         new HelloJni().displayHelloJni();  
11.     }  
12. } 

在class文件生成的相应目录执行命令如下:
----------------------------------------------------
E:\projects\jni\target\classes>javah HelloJni
----------------------------------------------------

得到C++文件HelloJni.h
Cpp代码 
1. /* DO NOT EDIT THIS FILE - it is machine generated */ 
2. #include <jni.h>  
3. /* Header for class HelloJni */ 
4.  
5. #ifndef _Included_HelloJni  
6. #define _Included_HelloJni  
7. #ifdef __cplusplus  
8. extern "C" {  
9. #endif  
10. /* 
11. * Class:     HelloJni 
12. * Method:    displayHelloJni 
13. * Signature: ()V 
14. */ 
15. JNIEXPORT void JNICALL Java_HelloJni_displayHelloJni  
16.   (JNIEnv *, jobject);  
17.  
18. #ifdef __cplusplus  
19. }  
20. #endif  
21. #endif 

JNI函数名称分为三部分:首先是Java关键字,供Java虚拟机识别;然后是调用者类名称(全限定的类名,其中用下划线代替名称分隔符);最后是对应的方法名称,各段名称之间用下划线分割。

JNI函数的参数也由三部分组成:首先是JNIEnv *,是一个指向JNI运行环境的指针;第二个参数随本地方法是静态还是非静态而有所不同一一非静态本地方法的第二个参数是对对象的引用,而静态本地方法的第二个参数是对其Java类的引用;其余的参数对应通常Java方法的参数,参数类型需要根据一定规则进行映射。


编写C++文件HelloJni.h的实现类,我是比较常用VC6.0来生成dll文件(helloJni.dll)的
Cpp代码 
1. #include <jni.h>  
2. #include "HelloJni.h"  
3. #include <stdio.h>  
4.  
5. JNIEXPORT void JNICALL   
6. Java_HelloJni_displayHelloJni(JNIEnv *env, jobject obj)   
7. {  
8.     printf("Hello Dynamic Link Library has been calling!\n");  
9.     printf("Java_HelloJni_displayHelloJni method has been executed!\n");  
10.     return;  
11. } 

其实此时,我们的工程目前还暂时不能生成我们想要的 helloJni.dll 文件,问题就出在了“#include <jni.h>”。由于VC6.0里没有我们需要的“jni.h”文件,因此就需要手动加入到VC6.0的环境中去。在JAVA_HOME路径下我们可以找到include文件夹,其中就可以找到我们需要的“jni.h”文件。为了避免以后麻烦起见,将所有的C++文件全部拿出来,放在“%CPP_HOME%\VC98\Include”路径下。然后将工程进行打包就可以得到我们需要的“helloJni.dll”文件了。

将helloJni.dll文件放置于工程classes目录,执行命令如下:
-----------------------------------------------
E:\projects\jni\target\classes>java HelloJni
-----------------------------------------------
运行结果如下:
-----------------------------------------------------------------
Hello Dynamic Link Library has been calling!
Java_HelloJni_displayHelloJni method has been executed!
-----------------------------------------------------------------

但是要想在eclipse中运行helloJni.dll文件,就需要将文件拷贝到工程的根目录,或者将其放在诸如C:\WINDOWS\system32;C:\WINDOWS;等目录下。因为,eclipse在运行helloJni.dll文件时首先会去在当前根目录找,如果找不到则在path上去找,因此你还可以为了方便管理生成的dll文件,将所有工程中的dll文件都放到一个特定的目录,然后将该目录加入到你的本地path环境变量中去,这样每次只需要将生成的dll文件放入path目录下就可以访问了。注,如果需要加环境变量最好在加好以后重新启动一下eclipse,确保eclipse能够加载到最新的path环境。

接下来,对小例子进行重构:
1. 新增一个基础类

Java代码 
1. package org.danlley.jni.test;  
2.  
3. public class BaseClass {  
4.  
5.     public BaseClass(String arg) {  
6.         loadLibrary(arg);  
7.     }  
8.  
9.     private static void loadLibrary(String arg) {  
10.         System.loadLibrary(arg);  
11.     }  
12. } 

2. 定义新类继承基础类

Java代码 
1. package org.danlley.jni.test;  
2.  
3. public class HelloJniTest extends BaseClass {  
4.     public HelloJniTest(String arg){  
5.         super(arg);  
6.     }  
7.     public native void displayHelloJni();  
8. } 

3. 编写调用类
Java代码 
1. package org.danlley.jni.test;  
2.  
3. public class RunMain {  
4.     public static void main(String[] args) {  
5.         new HelloJniTest("helloJniTest").displayHelloJni();  
6.     }  
7. } 
此次,将dll文件定义为:helloJniTest.dll。

执行结果:
------------------------------------------------------------------------------------
Java_org_danlley_jni_test_HelloJniTest_displayHelloJni has been called!
------------------------------------------------------------------------------------

例子相当简单,没有传入参数,也没有返回值,那么是不是可以让本地方法返回一些参数,同时又可以传入数据进行处理,并把处理结果返回给方法的调用者呢,先拿基本类型开刀。接下来对 HelloJniTest 继续进行改造:新增两个本地方法,如下:
Java代码 
1. package org.danlley.jni.test;  
2.  
3. public class HelloJniTest extends BaseClass {  
4.     public HelloJniTest(String arg){  
5.         super(arg);  
6.     }  
7.     public native void displayHelloJni();  
8.       
9.     public native int getDynamicIntDataNoParam();  
10.       
11.     public native int getDynamicIntData(int i);  
12. } 

重新生成org_danlley_jni_test_HelloJniTest.h文件,并改写其实现类org_danlley_jni_test_HelloJniTest.cpp如下:
Cpp代码 
1. // org_danlley_jni_test_HelloJniTest.cpp: implementation of the org_danlley_jni_test_HelloJniTest class.  
2. //  
3. //////////////////////////////////////////////////////////////////////  
4.  
5. #include "org_danlley_jni_test_HelloJniTest.h"  
6. #include <jni.h>  
7. #include <stdio.h>  
8.  
9. JNIEXPORT void JNICALL   
10. Java_org_danlley_jni_test_HelloJniTest_displayHelloJni(JNIEnv *env, jobject obj)   
11. {  
12.     printf("Java_org_danlley_jni_test_HelloJniTest_displayHelloJni has been called!\n");  
13.     return;  
14. }  
15.  
16. JNIEXPORT jint JNICALL   
17. Java_org_danlley_jni_test_HelloJniTest_getDynamicIntDataNoParam(JNIEnv *env, jobject obj)   
18. {  
19.     return 65535;  
20. }  
21.  
22. JNIEXPORT jint JNICALL   
23. Java_org_danlley_jni_test_HelloJniTest_getDynamicIntData(JNIEnv *env, jobject obj, jint i)  
24. {  
25.     i*=i;  
26.     return i;  
27. } 

修改 RunMain 类:
Java代码 
1. package org.danlley.jni.test;  
2.  
3. public class RunMain {  
4.     public static void main(String[] args) {  
5.         HelloJniTest tester=new HelloJniTest("helloJniTest");  
6.         tester.displayHelloJni();  
7.         int i=tester.getDynamicIntDataNoParam();  
8.         System.out.println("tester.getDynamicIntDataNoParam()="+i);  
9.         int j=tester.getDynamicIntData(100);  
10.         System.out.println("tester.getDynamicIntData(100)="+j);  
11.     }  
12. } 

运行RunMain:
-----------------------------------------------------------------------
tester.getDynamicIntDataNoParam()=65535
tester.getDynamicIntData(100)=10000
Java_org_danlley_jni_test_HelloJniTest_displayHelloJni has been called!
-----------------------------------------------------------------------
OK,一切正常。

还是不过瘾,简单对象可以处理了,如果是一个java对象,还可以处理吗,答案是当然可以,接下来我们来继续对 helloJniTest 类进行改造。新增一个方法如下:
Java代码 
1. package org.danlley.jni.test;  
2.  
3. public class HelloJniTest extends BaseClass {  
4.     public HelloJniTest(String arg){  
5.         super(arg);  
6.     }  
7.     public native void displayHelloJni();  
8.       
9.     public native int getDynamicIntDataNoParam();  
10.       
11.     public native int getDynamicIntData(int i);  
12.       
13.     public native String getDynamicStringData(String arg);  
14. } 

重新生成org_danlley_jni_test_HelloJniTest.h文件:
Cpp代码 
1. /* DO NOT EDIT THIS FILE - it is machine generated */ 
2. #include <jni.h>  
3. /* Header for class org_danlley_jni_test_HelloJniTest */ 
4.  
5. #ifndef _Included_org_danlley_jni_test_HelloJniTest  
6. #define _Included_org_danlley_jni_test_HelloJniTest  
7. #ifdef __cplusplus  
8. extern "C" {  
9. #endif  
10. /* 
11. * Class:     org_danlley_jni_test_HelloJniTest 
12. * Method:    displayHelloJni 
13. * Signature: ()V 
14. */ 
15. JNIEXPORT void JNICALL Java_org_danlley_jni_test_HelloJniTest_displayHelloJni  
16.   (JNIEnv *, jobject);  
17.  
18. /* 
19. * Class:     org_danlley_jni_test_HelloJniTest 
20. * Method:    getDynamicIntDataNoParam 
21. * Signature: ()I 
22. */ 
23. JNIEXPORT jint JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicIntDataNoParam  
24.   (JNIEnv *, jobject);  
25.  
26. /* 
27. * Class:     org_danlley_jni_test_HelloJniTest 
28. * Method:    getDynamicIntData 
29. * Signature: (I)I 
30. */ 
31. JNIEXPORT jint JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicIntData  
32.   (JNIEnv *, jobject, jint);  
33.  
34. /* 
35. * Class:     org_danlley_jni_test_HelloJniTest 
36. * Method:    getDynamicStringData 
37. * Signature: (Ljava/lang/String;)Ljava/lang/String; 
38. */ 
39. JNIEXPORT jstring JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicStringData  
40.   (JNIEnv *, jobject, jstring);  
41.  
42. #ifdef __cplusplus  
43. }  
44. #endif  
45. #endif 

改写org_danlley_jni_test_HelloJniTest.cpp文件:
Cpp代码 
1. // org_danlley_jni_test_HelloJniTest.cpp: implementation of the org_danlley_jni_test_HelloJniTest class.  
2. //  
3. //////////////////////////////////////////////////////////////////////  
4.  
5. #include "org_danlley_jni_test_HelloJniTest.h"  
6. #include <jni.h>  
7. #include <stdio.h>  
8.  
9. JNIEXPORT void JNICALL   
10. Java_org_danlley_jni_test_HelloJniTest_displayHelloJni(JNIEnv *env, jobject obj)   
11. {  
12.     printf("Java_org_danlley_jni_test_HelloJniTest_displayHelloJni has been called!\n");  
13.     return;  
14. }  
15.  
16. JNIEXPORT jint JNICALL   
17. Java_org_danlley_jni_test_HelloJniTest_getDynamicIntDataNoParam(JNIEnv *env, jobject obj)   
18. {  
19.     return 65535;  
20. }  
21.  
22. JNIEXPORT jint JNICALL   
23. Java_org_danlley_jni_test_HelloJniTest_getDynamicIntData(JNIEnv *env, jobject obj, jint i)  
24. {  
25.     i*=i;  
26.     return i;  
27. }  
28.  
29. JNIEXPORT jstring JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicStringData  
30. (JNIEnv *env, jobject obj, jstring arg){  
31.     //Get the native string from javaString  
32.     const char *nativeString = env->GetStringUTFChars(arg, 0);  
33.     printf("%s", nativeString);  
34.     //DON'T FORGET THIS LINE!!!  
35.     env->ReleaseStringUTFChars(arg, nativeString);  
36.     return arg;  
37. } 
 
重新对C++工程打包成dll文件,运行结果:
---------------------------------------------------------------------------
tester.getDynamicIntDataNoParam()=65535
tester.getDynamicIntData(100)=10000
tester.getDynamicStringData=My first String test
Java_org_danlley_jni_test_HelloJniTest_displayHelloJni has been called!
My first String test
---------------------------------------------------------------------------
我们不仅把Java的一个String对象成功的传给了dll,而且还将处理后的结果返回了出来。

但是总觉得还是不够,那我们就再来个比较复杂的对象把,我们这次将一个整形数组通过java传给dll,看看是不是也可以处理,继续还是对 helloJniTest 类进行改造,新增一个方法:
Java代码 
1. package org.danlley.jni.test;  
2.  
3. public class HelloJniTest extends BaseClass {  
4.     public HelloJniTest(String arg){  
5.         super(arg);  
6.     }  
7.     public native void displayHelloJni();  
8.       
9.     public native int getDynamicIntDataNoParam();  
10.       
11.     public native int getDynamicIntData(int i);  
12.       
13.     public native String getDynamicStringData(String arg);  
14.       
15.     public native int[] getDynamicArrayData(int[] args);  
16. } 

重新生成org_danlley_jni_test_HelloJniTest.h文件
Cpp代码 
1. /* DO NOT EDIT THIS FILE - it is machine generated */ 
2. #include <jni.h>  
3. /* Header for class org_danlley_jni_test_HelloJniTest */ 
4.  
5. #ifndef _Included_org_danlley_jni_test_HelloJniTest  
6. #define _Included_org_danlley_jni_test_HelloJniTest  
7. #ifdef __cplusplus  
8. extern "C" {  
9. #endif  
10. /* 
11. * Class:     org_danlley_jni_test_HelloJniTest 
12. * Method:    displayHelloJni 
13. * Signature: ()V 
14. */ 
15. JNIEXPORT void JNICALL Java_org_danlley_jni_test_HelloJniTest_displayHelloJni  
16.   (JNIEnv *, jobject);  
17.  
18. /* 
19. * Class:     org_danlley_jni_test_HelloJniTest 
20. * Method:    getDynamicIntDataNoParam 
21. * Signature: ()I 
22. */ 
23. JNIEXPORT jint JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicIntDataNoParam  
24.   (JNIEnv *, jobject);  
25.  
26. /* 
27. * Class:     org_danlley_jni_test_HelloJniTest 
28. * Method:    getDynamicIntData 
29. * Signature: (I)I 
30. */ 
31. JNIEXPORT jint JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicIntData  
32.   (JNIEnv *, jobject, jint);  
33.  
34. /* 
35. * Class:     org_danlley_jni_test_HelloJniTest 
36. * Method:    getDynamicStringData 
37. * Signature: (Ljava/lang/String;)Ljava/lang/String; 
38. */ 
39. JNIEXPORT jstring JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicStringData  
40.   (JNIEnv *, jobject, jstring);  
41.  
42. /* 
43. * Class:     org_danlley_jni_test_HelloJniTest 
44. * Method:    getDynamicArrayData 
45. * Signature: ([I)[I 
46. */ 
47. JNIEXPORT jintArray JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicArrayData  
48.   (JNIEnv *, jobject, jintArray);  
49.  
50. #ifdef __cplusplus  
51. }  
52. #endif  
53. #endif 

改写org_danlley_jni_test_HelloJniTest.cpp文件:
Cpp代码 
1. // org_danlley_jni_test_HelloJniTest.cpp: implementation of the org_danlley_jni_test_HelloJniTest class.  
2. //  
3. //////////////////////////////////////////////////////////////////////  
4.  
5. #include "org_danlley_jni_test_HelloJniTest.h"  
6. #include <jni.h>  
7. #include <stdio.h>  
8.  
9. JNIEXPORT void JNICALL   
10. Java_org_danlley_jni_test_HelloJniTest_displayHelloJni(JNIEnv *env, jobject obj)   
11. {  
12.     printf("Java_org_danlley_jni_test_HelloJniTest_displayHelloJni has been called!\n");  
13.     return;  
14. }  
15.  
16. JNIEXPORT jint JNICALL   
17. Java_org_danlley_jni_test_HelloJniTest_getDynamicIntDataNoParam(JNIEnv *env, jobject obj)   
18. {  
19.     return 65535;  
20. }  
21.  
22. JNIEXPORT jint JNICALL   
23. Java_org_danlley_jni_test_HelloJniTest_getDynamicIntData(JNIEnv *env, jobject obj, jint i)  
24. {  
25.     i*=i;  
26.     return i;  
27. }  
28.  
29. JNIEXPORT jstring JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicStringData  
30. (JNIEnv *env, jobject obj, jstring arg){  
31.     //Get the native string from javaString  
32.     const char *nativeString = env->GetStringUTFChars(arg, 0);  
33.     printf("%s", nativeString);  
34.     //DON'T FORGET THIS LINE!!!  
35.     env->ReleaseStringUTFChars(arg, nativeString);  
36.     return arg;  
37. }  
38.  
39.  
40. JNIEXPORT jintArray JNICALL Java_org_danlley_jni_test_HelloJniTest_getDynamicArrayData  
41. (JNIEnv *env, jobject  obj, jintArray args){  
42.     jint buf[10];  
43.     jint i;  
44.     env->GetIntArrayRegion(args, 0, 10, buf);  
45.     jint j=0;  
46.     for (i = 0; i < 10; i++) {  
47.         j=buf[i];  
48.         j*=j;  
49.         buf[i]=j;  
50.     }  
51.     env->SetIntArrayRegion(args, 0, 10, buf);  
52.     return args;  
53. } 

改写RunMain:
Java代码 
1. package org.danlley.jni.test;  
2.  
3. public class RunMain {  
4.     public static void main(String[] args) {  
5.         HelloJniTest tester = new HelloJniTest("helloJniTest");  
6.         tester.displayHelloJni();  
7.         int i = tester.getDynamicIntDataNoParam();  
8.         System.out.println("tester.getDynamicIntDataNoParam()=" + i);  
9.         int j = tester.getDynamicIntData(100);  
10.         System.out.println("tester.getDynamicIntData(100)=" + j);  
11.         String str = tester.getDynamicStringData("My first String test");  
12.         System.out.println("tester.getDynamicStringData=" + str);  
13.         int[] args_int = new int[10];  
14.         for (int ii = 0; ii < 10; ii++) {  
15.             args_int[ii] = ii;  
16.         }  
17.         int[] args_arr = tester.getDynamicArrayData(args_int);  
18.         for (int ii = 0; ii < 10; ii++) {  
19.             System.out.println(args_arr[ii]);  
20.         }  
21.     }  
22. } 

运行结果:
--------------------------------------------------------------------------------
tester.getDynamicIntDataNoParam()=65535
tester.getDynamicIntData(100)=10000
tester.getDynamicStringData=My first String test
0
1
4
9
16
25
36
49
64
81
Java_org_danlley_jni_test_HelloJniTest_displayHelloJni has been called!
My first String test
--------------------------------------------------------------------------------
分享到:
评论

相关推荐

    Java JNI 编程进阶

    JNI技术只是针对一些严重影响Java性能的代码段,该部分可能只占源程序的极少部分,所以几乎可以不考虑该部分代码在主流平台之间移植的工作量。同时,也不必过分担心类型匹配问题,我们完全可以控制代码不出现这种...

    Java_JNI_编程进阶

    Java_JNI_编程进阶 android 学习之

    Java_JNI_编程进阶.pdf

    Java_JNI_编程进阶.pdf

    Java-JNI-编程进阶.doc

    Java-JNI-编程进阶.

    JNI技术手册 c/c++调用java

    IV. Java JNI 编程进阶 18 一、 解决性能问题 18 二、 解决本机平台接口调用问题 19 三、 嵌入式开发应用(JNI小例子) 20 1、 新增一个基础类 22 2、 定义新类继承基础类 23 3、 编写调用类 23 4、 新增两个本地方法 ...

    JNI技术各类文档

    jni详解 JNI设计实践之路 JNI技术手册 Java_JNI_编程进阶 android_jni操作指南

    5本 jni 资料

    5本JNI资料,非常详细; 1.android_jni操作指南.pdf 2.JNI设计实践之路.pdf 3.jni详解.pdf 4.Java_JNI_编程进阶.pdf 5.Android_JNI总结.doc

    使用JNI进行混合编程:在Java中调用C/C++本地库

    NULL 博文链接:https://conkeyn.iteye.com/blog/1597188

    JNI编程指南.zip

    【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或...

    Rust与Java进行交互实例代码

    使用JNI技术,实现Rust与JAVA的相互调用,从而提高执行效率,本资源是文章《【一起学Rust | 进阶篇 | jni库】JNI实现Java与Rust进行交互》的配套案例代码,供读者进行学习,查看,以提升自己的编程能力。

    老罗android开发视频教程全集百度网盘下载

    Android进阶初级:组件Widget/ 菜单Menu/ 布局Layout 详解 Xml解析(Pull/Dom/Sax)/JNI 解析SQL数据库原理, SQLit e /SharedPreferences/File详解 多媒体Audio/Video/Camera 详解 Android进阶高级:蓝牙/WIFI SMS/...

    黑马程序员安卓Android52期培训课

    2014/12/17 星期三 xml&dom_sax&dom4j编程 2014/12/18 星期四 2014/12/19 星期五 tomcat与web程序结构与Http协议 2014/12/20 星期六 java web之servlet 2014/12/21 星期日 java web之request/respone 2014/12/22 ...

    android开发艺术探索高清完整版PDF

    / 463 13.4 反编译初步 / 469 13.4.1 使用dex2jar和jd—gui反编译apk / 470 13.4.2 使用apktool对apk进行二次打包 / 470 第14章 JNI和NDK编程 / 473 14.1 JNI的开发流程 / 474 14.2 NDK的开发流程 / 478 14.3...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    14.4 JNI调用Java方法的流程 486 第15章 Android性能优化 489 15.1 Android的性能优化方法 490 15.1.1 布局优化 490 15.1.2 绘制优化 493 15.1.3 内存泄露优化 493 15.1.4 响应速度优化和ANR日志分析 496 ...

    Android开发艺术探索

     14.4 JNI调用Java方法的流程 / 486  第15章 Android性能优化 / 489  15.1 Android的性能优化方法 / 490  15.1.1 布局优化 / 490  15.1.2 绘制优化 / 493  15.1.3 内存泄露优化 / 493  15.1.4 响应速度优化和...

Global site tag (gtag.js) - Google Analytics