资源预览内容
第1页 / 共17页
第2页 / 共17页
第3页 / 共17页
第4页 / 共17页
第5页 / 共17页
第6页 / 共17页
第7页 / 共17页
第8页 / 共17页
第9页 / 共17页
第10页 / 共17页
亲,该文档总共17页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
boe让开发更简单,做最棒的移动开发者社区http:/www.eoe.cn更多Androids iOS、WP学习资料访问 www.eoe.cnEOGeoe移动开发者社区www.eoe.c n负责?:朔月 &futurexiong分任务链接地址: http:/developer.android.com/guide/practices/j ni.htmlJNI Tips-JNI 技巧JNI是Java本地接?(Java Native In terface)的简称。它定义了托管代码(用Java编程语言写的)与本地代码 佣C/C+写的)交 互的?种方式(译者注:这里的托管代码应该理解成受 Java运行时环境监管的代码)。它与?商无关,支持从动态共享库中 加载代码,虽然繁琐但有时是合理有效的。你应该通读JNI spec for J2SE 6来获取对JNI是如何?作的以及它有什么可用的功能的?个认知。在你读第?遍的时候可能对JNI的某些方面的理解不会立刻就清晰,所以你会发现?下的章节可能会对你有所帮助JNI Programmers Guide andSpecification里有更为详细的资料。JavaVM and JNIEnv-JavaVM 和 JNIEnvJNI定义了 2种关键的数据结构,JavaVM和JNIEnv。它们本质上都是指向函数表的指针的指针。 (在C+的版本中,它 们被定义成类(译者注:准确来说是C+中的结构体),类里面包含 ?个指向函数表的指针,以及与JNI函数?对应的用来间 接访问函数表的成员函数。 JavaVM提供了 调用接? “的函数,允许你创建和销毁 ?JvaVM。理论上每个进程你可以有 多个JavaVM,但An droid只允许有 ?个。JNIEnv提供了?多数的NI函数。你的本地方法都会接收 JNIEnv作为第?个参数。JNIEnv用于本地线程存储。因此,你不能在线程间共享同JNIEnv。如果?个代码段没有其他方式获取它自身线程的JNIEnv ,你可以共享JavaVM,用GetEnv来获取线程的JNIEnv。(假设这个线程有JavaVM;参见下面的AttachCurrentThread 。)C版本的JNIEnv和JavaVM的声明是异于C+版本的。jni.h头文件根据被包含在C或是C+文件中来提供不同类型的 typedefs。因此在被两种语言包含的头文件中包含 JNIEnv参数不是明智的选择。(换句话说:如果你的头文件中需要用到 #ifdef _cplusplus,那么在有涉及到JNIEnv的内容的时候你需要做?些额外)的?作。Threads-线程所有的线程都是Linux的线程,由内核调度。它们通常由托管代码启动(使用Thread.start),但是也可以在别的地方创建它们,并把它们连接到JavaVM上。比如, ?个由pthread_create方法启动的线程可以用 JNI的AttachCurrentThread 或者 AttachCurrentThreadAsDaemon函数来连接。在线程没有被连接到 JavaVM之前是不会有JNIEnv的,也无法发起JNI的调用。连接?个本地创建的线程会构造?4java.lang.Thread的对象,并把这个对象添加到“主线程组里面,使之对调试者可见。对?个已被连接的线程调用 AttachCurre ntThread不做任何操作。An droid不会暂停正在执行本地代码的线程。如果垃圾收集器正在运行,或者是调试者发岀了暂停的请求,An droid会在它发起下?个JNI调用的时候暂停线程。通过JNI连接的线程在它们退岀之前必须调用 DetachCurre ntThread 方法。如果直接编写这样的调用代码会显得很笨拙,在An droid2.0(Eclair)及更高的版本,你可以使用 pthread_key_create 来定义?个析构函数,并在析构函数里调用DetachCurre ntThread 方法,析构函数会在线程退岀之前被调用。jclass, jmethodID, and jfieldID如果你想在本地代码中访问?个对象的字段,你将会做以下事情:*取得FindClass得到的类的类对象引用*取得GetFieldID得到的字段的字段ID *用合适的方法取得字段的内容,比如 GetIntField同样的,要调用 ?个方法,你必须先得到?个类对象的引用和方法ID。这些ID通常来说只是指向内部的运行时数据结构。#/12eoe移动开发者社区www.eoe.cn找到它们可能需要?些字符串的比较,但?旦你得到它们之后实际的字段取值或者方法调用将会非常的快。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 clear 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函数:DeleteGlobalRefDeleteLocalRefDeleteWeakGlobalRefExcepti 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 checking 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.多数JNI在被调用时能够抛岀?个异常,但通常还有?种更简单的方式来检验该调用是否岀现失效。比如说,如果调用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. The 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指令仅仅只是在当前的线程中设置了?个异常处理指针,而当从本地代码返回托管代码时,该异常才能被标注并得到有效的处理。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或者ExceptionOccurred函数来捕获相应的异常,也能通过调用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;, 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
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号