【Android开发API】更好的策略-JNI使用技巧-JNITips

上传人:壹****1 文档编号:507063679 上传时间:2022-09-04 格式:DOC 页数:17 大小:239.50KB
返回 下载 相关 举报
【Android开发API】更好的策略-JNI使用技巧-JNITips_第1页
第1页 / 共17页
【Android开发API】更好的策略-JNI使用技巧-JNITips_第2页
第2页 / 共17页
【Android开发API】更好的策略-JNI使用技巧-JNITips_第3页
第3页 / 共17页
【Android开发API】更好的策略-JNI使用技巧-JNITips_第4页
第4页 / 共17页
【Android开发API】更好的策略-JNI使用技巧-JNITips_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《【Android开发API】更好的策略-JNI使用技巧-JNITips》由会员分享,可在线阅读,更多相关《【Android开发API】更好的策略-JNI使用技巧-JNITips(17页珍藏版)》请在金锄头文库上搜索。

1、boe让开发更简单,做最棒的移动开发者社区http:/更多Androids iOS、WP学习资料访问 EOGeoe移动开发者社区www.eoe.c n负责?:朔月 &futurexiong分任务链接地址: http:/ ni.htmlJNI Tips-JNI 技巧JNI是Java本地接?(Java Native In terface)的简称。它定义了托管代码(用Java编程语言写的)与本地代码 佣C/C+写的)交 互的?种方式(译者注:这里的托管代码应该理解成受 Java运行时环境监管的代码)。它与?商无关,支持从动态共享库中 加载代码,虽然繁琐但有时是合理有效的。你应该通读JNI spec

2、for J2SE 6来获取对JNI是如何?作的以及它有什么可用的功能的?个认知。在你读第?遍的时候可能对JNI的某些方面的理解不会立刻就清晰,所以你会发现?下的章节可能会对你有所帮助JNI Programmers Guide andSpecification里有更为详细的资料。JavaVM and JNIEnv-JavaVM 和 JNIEnvJNI定义了 2种关键的数据结构,JavaVM和JNIEnv。它们本质上都是指向函数表的指针的指针。 (在C+的版本中,它 们被定义成类(译者注:准确来说是C+中的结构体),类里面包含 ?个指向函数表的指针,以及与JNI函数?对应的用来间 接访问函数表的成

3、员函数。 JavaVM提供了 调用接? “的函数,允许你创建和销毁 ?JvaVM。理论上每个进程你可以有 多个JavaVM,但An droid只允许有 ?个。JNIEnv提供了?多数的NI函数。你的本地方法都会接收 JNIEnv作为第?个参数。JNIEnv用于本地线程存储。因此,你不能在线程间共享同JNIEnv。如果?个代码段没有其他方式获取它自身线程的JNIEnv ,你可以共享JavaVM,用GetEnv来获取线程的JNIEnv。(假设这个线程有JavaVM;参见下面的AttachCurrentThread 。)C版本的JNIEnv和JavaVM的声明是异于C+版本的。jni.h头文件根据被

4、包含在C或是C+文件中来提供不同类型的 typedefs。因此在被两种语言包含的头文件中包含 JNIEnv参数不是明智的选择。(换句话说:如果你的头文件中需要用到 #ifdef _cplusplus,那么在有涉及到JNIEnv的内容的时候你需要做?些额外)的?作。Threads-线程所有的线程都是Linux的线程,由内核调度。它们通常由托管代码启动(使用Thread.start),但是也可以在别的地方创建它们,并把它们连接到JavaVM上。比如, ?个由pthread_create方法启动的线程可以用 JNI的AttachCurrentThread 或者 AttachCurrentThread

5、AsDaemon函数来连接。在线程没有被连接到 JavaVM之前是不会有JNIEnv的,也无法发起JNI的调用。连接?个本地创建的线程会构造?4java.lang.Thread的对象,并把这个对象添加到“主线程组里面,使之对调试者可见。对?个已被连接的线程调用 AttachCurre ntThread不做任何操作。An droid不会暂停正在执行本地代码的线程。如果垃圾收集器正在运行,或者是调试者发岀了暂停的请求,An droid会在它发起下?个JNI调用的时候暂停线程。通过JNI连接的线程在它们退岀之前必须调用 DetachCurre ntThread 方法。如果直接编写这样的调用代码会显得

6、很笨拙,在An droid2.0(Eclair)及更高的版本,你可以使用 pthread_key_create 来定义?个析构函数,并在析构函数里调用DetachCurre ntThread 方法,析构函数会在线程退岀之前被调用。jclass, jmethodID, and jfieldID如果你想在本地代码中访问?个对象的字段,你将会做以下事情:*取得FindClass得到的类的类对象引用*取得GetFieldID得到的字段的字段ID *用合适的方法取得字段的内容,比如 GetIntField同样的,要调用 ?个方法,你必须先得到?个类对象的引用和方法ID。这些ID通常来说只是指向内部的运行

7、时数据结构。#/12eoe移动开发者社区找到它们可能需要?些字符串的比较,但?旦你得到它们之后实际的字段取值或者方法调用将会非常的快。Excepti ons- 异常处理You must not call most JNI fun cti ons while an excepti on is pending. Your code is expected to no tice the excepti on (viathe fun cti ons retur n value, Excepti on Check, or Excepti onO ccurred) and retur n, or clea

8、r the excepti on and han dle it.?多数情况下,当程序发生异常的时候你是无法调用JNI模块的。因为你的代码不但需要标记岀异常岀现的位置(可以通过ExceptionCheck或者ExceptionOccurred的返回值),而且需要对这些所抛岀的异常进行处理。The only JNI functions that you are allowed to call while an exception is pending are:仅在以下异常被抛岀时,你可以调用JNI函数:DeleteGlobalRefDeleteLocalRefDeleteWeakGlobalRef

9、Excepti on CheckExcepti on ClearException DescribeExcepti onO ccurredMon itorExitPopLocalFramePushLocalFrameReleaseArrayEleme ntsReleasePrimitiveArrayCriticalReleaseStr in gCharsReleaseStri ngCriticalReleaseStri ngUTFCharsMany JNI calls can throw an exception, but often provide a simpler way of chec

10、king for failure. For example, ifNewString returns a non-NULL value, you dont need to check for an exception. However, if you call a method (using afunction like CallObjectMethod), you must always check for an exception, because the return value is not going to bevalid if an exception was thrown.多数J

11、NI在被调用时能够抛岀?个异常,但通常还有?种更简单的方式来检验该调用是否岀现失效。比如说,如果调用NewString方法返回?个日非值,那么你就不需要再对其进行异常检查。但如果你调用的是CallObjectMethod这?个类似样的函数时,你还是必须做异常的检查处理,这是因为当岀现异常时,调用该模块并不会返回?个有效值。Note that excepti ons throw n by in terpreted code do not unwind n ative stack frames, and An droid does not yet supportC+ excepti ons. Th

12、e JNI Throw and ThrowNew in structi ons just set an excepti on poin ter in the curre nt thread. Uponreturni ng to man aged from n ative code, the excepti on will be no ted and han dled appropriately.需要注意的是,由翻译码抛岀的异常并不会释放堆栈帧空间,且目前的An droid系统也不支持C+异常处理。所以JNI的Throw和ThrowNew指令仅仅只是在当前的线程中设置了?个异常处理指针,而当从本

13、地代码返回托管代码时,该异常才能被标注并得到有效的处理。Native code can catch an excepti on by call ing Excepti on Check or Excepti onO ccurred, and clear it with#/12&oeeoe移动开发者社区www.eoe.c nExcepti on Clear. As usual, discard ing excepti ons without han dli ng them can lead to problems.当然,本地代码可以通过调用ExceptionCheck或者ExceptionOcc

14、urred函数来捕获相应的异常,也能通过调用ExceptionClear函数来清理该异常。同样,如果对抛岀的异常不作处理也会造成问题。There are no built-in functions for manipulating the Throwable object itself, so if you want to (say) get the exception stri ng you will n eed to find the Throwable class, look up the method ID for getMessage ()Ljava/la ng/Stri ng;,

15、i nvoke it, and if the result is non-N ULL use GetStri ngUTFChars to get somethi ng you can hand to prin tf(3) or equivale nt.由于对Throwable对象的操作不支持内置函数,所以如果你需要获取相应的异常字符串,你首先需要找到Throwable类,然后找到getMessage ()Ljava/lang/String;方法的】D,调用它,假如调用后返回的结果是非null值,则需要通过GetStringUTFChars方法来把获取的结果传给printf(3)或者是采用其他类似的方法完成这个?作。JNI does very little error check ing. Errors usually result in a crash. An droid also offers a mode called CheckJNI, wherethe JavaVM and JNIEnv function table pointers are swit

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号