【Android開發(fā)API】更好的策略-JNI使用技巧-JNITips_第1頁
【Android開發(fā)API】更好的策略-JNI使用技巧-JNITips_第2頁
【Android開發(fā)API】更好的策略-JNI使用技巧-JNITips_第3頁
【Android開發(fā)API】更好的策略-JNI使用技巧-JNITips_第4頁
【Android開發(fā)API】更好的策略-JNI使用技巧-JNITips_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、boe讓開發(fā)更簡單,做最棒的移動開發(fā)者社區(qū)更多Androids iOS、WP學習資料訪問 EOGeoe移動開發(fā)者社區(qū)www.eoe.c n負責?:朔月 &futurexiong分任務(wù)鏈接地址: ni.htmlJNI Tips-JNI 技巧JNI是Java本地接?(Java Native In terface)的簡稱。它定義了托管代碼(用Java編程語言寫的)與本地代碼 傭C/C+寫的)交 互的?種方式(譯者注:這里的托管代碼應(yīng)該理解成受 Java運行時環(huán)境監(jiān)管的代碼)。它與?商無關(guān),支持從動態(tài)共享庫中 加載代碼,雖然繁瑣但有時是合理有效的。你應(yīng)該通讀JNI spec for J2SE

2、6來獲取對JNI是如何?作的以及它有什么可用的功能的?個認知。在你讀第?遍的時候可能對JNI的某些方面的理解不會立刻就清晰,所以你會發(fā)現(xiàn)?下的章節(jié)可能會對你有所幫助JNI Programmer's Guide andSpecification里有更為詳細的資料。JavaVM and JNIEnv-JavaVM 和 JNIEnvJNI定義了 2種關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),"JavaVM"和"JNIEnv"。它們本質(zhì)上都是指向函數(shù)表的指針的指針。 (在C+的版本中,它 們被定義成類(譯者注:準確來說是C+中的結(jié)構(gòu)體),類里面包含 ?個指向函數(shù)表的指針,以及與J

3、NI函數(shù)?對應(yīng)的用來間 接訪問函數(shù)表的成員函數(shù)。 JavaVM提供了 "調(diào)用接? “的函數(shù),允許你創(chuàng)建和銷毀 ?JvaVM。理論上每個進程你可以有 多個JavaVM,但An droid只允許有 ?個。JNIEnv提供了?多數(shù)的NI函數(shù)。你的本地方法都會接收 JNIEnv作為第?個參數(shù)。JNIEnv用于本地線程存儲。因此,你不能在線程間共享同JNIEnv。如果?個代碼段沒有其他方式獲取它自身線程的JNIEnv ,你可以共享JavaVM,用GetEnv來獲取線程的JNIEnv。(假設(shè)這個線程有JavaVM;參見下面的AttachCurrentThread 。)C版本的JNIEnv和Jav

4、aVM的聲明是異于C+版本的。"jni.h"頭文件根據(jù)被包含在C或是C+文件中來提供不同類型的 typedefs。因此在被兩種語言包含的頭文件中包含 JNIEnv參數(shù)不是明智的選擇。(換句話說:如果你的頭文件中需要用到 #ifdef _cplusplus,那么在有涉及到JNIEnv的內(nèi)容的時候你需要做?些額外)的?作。Threads-線程所有的線程都是Linux的線程,由內(nèi)核調(diào)度。它們通常由托管代碼啟動(使用Thread.start),但是也可以在別的地方創(chuàng)建它們,并把它們連接到JavaVM上。比如, ?個由pthread_create方法啟動的線程可以用 JNI的Atta

5、chCurrentThread 或者 AttachCurrentThreadAsDaemon函數(shù)來連接。在線程沒有被連接到 JavaVM之前是不會有JNIEnv的,也無法發(fā)起JNI的調(diào)用。連接?個本地創(chuàng)建的線程會構(gòu)造?4java.lang.Thread的對象,并把這個對象添加到“主"線程組里面,使之對調(diào)試者可見。對?個已被連接的線程調(diào)用 AttachCurre ntThread不做任何操作。An droid不會暫停正在執(zhí)行本地代碼的線程。如果垃圾收集器正在運行,或者是調(diào)試者發(fā)岀了暫停的請求,An droid會在它發(fā)起下?個JNI調(diào)用的時候暫停線程。通過JNI連接的線程在它們退岀之前必

6、須調(diào)用 DetachCurre ntThread 方法。如果直接編寫這樣的調(diào)用代碼會顯得很笨拙,在An droid2.0(Eclair)及更高的版本,你可以使用 pthread_key_create 來定義?個析構(gòu)函數(shù),并在析構(gòu)函數(shù)里調(diào)用DetachCurre ntThread 方法,析構(gòu)函數(shù)會在線程退岀之前被調(diào)用。jclass, jmethodID, and jfieldID如果你想在本地代碼中訪問?個對象的字段,你將會做以下事情:*取得FindClass得到的類的類對象引用*取得GetFieldID得到的字段的字段ID *用合適的方法取得字段的內(nèi)容,比如 GetIntField同樣的,要調(diào)

7、用 ?個方法,你必須先得到?個類對象的引用和方法ID。這些ID通常來說只是指向內(nèi)部的運行時數(shù)據(jù)結(jié)構(gòu)。3/12eoe移動開發(fā)者社區(qū)找到它們可能需要?些字符串的比較,但?旦你得到它們之后實際的字段取值或者方法調(diào)用將會非常的快。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 on's retur n value, Excepti on Ch

8、eck, or Excepti onO ccurred) and retur n, or clear the excepti on and han dle it.?多數(shù)情況下,當程序發(fā)生異常的時候你是無法調(diào)用JNI模塊的。因為你的代碼不但需要標記岀異常岀現(xiàn)的位置(可以通過ExceptionCheck或者ExceptionOccurred的返回值),而且需要對這些所拋岀的異常進行處理。The only JNI functions that you are allowed to call while an exception is pending are:僅在以下異常被拋岀時,你可以調(diào)用JNI函數(shù)

9、:DeleteGlobalRefDeleteLocalRefDeleteWeakGlobalRefExcepti on CheckExcepti on ClearException DescribeExcepti onO ccurredMon itorExitPopLocalFramePushLocalFrameReleaseArrayEleme ntsReleasePrimitiveArrayCriticalReleaseStr in gCharsReleaseStri ngCriticalReleaseStri ngUTFCharsMany JNI calls can throw an e

10、xception, but often provide a simpler way of checking for failure. For example, ifNewString returns a non-NULL value, you don't 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

11、is not going to bevalid if an exception was thrown.多數(shù)JNI在被調(diào)用時能夠拋岀?個異常,但通常還有?種更簡單的方式來檢驗該調(diào)用是否岀現(xiàn)失效。比如說,如果調(diào)用NewString方法返回?個日非值,那么你就不需要再對其進行異常檢查。但如果你調(diào)用的是CallObjectMethod這?個類似樣的函數(shù)時,你還是必須做異常的檢查處理,這是因為當岀現(xiàn)異常時,調(diào)用該模塊并不會返回?個有效值。Note that excepti ons throw n by in terpreted code do not unwind n ative stack frame

12、s, 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系統(tǒng)也不支持C+

13、異常處理。所以JNI的Throw和ThrowNew指令僅僅只是在當前的線程中設(shè)置了?個異常處理指針,而當從本地代碼返回托管代碼時,該異常才能被標注并得到有效的處理。Native code can "catch" an excepti on by call ing Excepti on Check or Excepti onO ccurred, and clear it with5/12&oeeoe移動開發(fā)者社區(qū)www.eoe.c nExcepti on Clear. As usual, discard ing excepti ons without han dli

14、ng them can lead to problems.當然,本地代碼可以通過調(diào)用ExceptionCheck或者ExceptionOccurred函數(shù)來捕獲相應(yīng)的異常,也能通過調(diào)用ExceptionClear函數(shù)來清理該異常。同樣,如果對拋岀的異常不作處理也會造成問題。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 Throwabl

15、e 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對象的操作不支持內(nèi)置函數(shù),所以如果你需要獲取相應(yīng)的異常字符串,你首先需要找到Throwable類,然后找到getMessage "()Ljava/la

16、ng/String;方法的'】D,調(diào)用它,假如調(diào)用后返回的結(jié)果是非null值,則需要通過GetStringUTFChars方法來把獲取的結(jié)果傳給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 switched to tables of fu

17、nctions that perform an extended series of checks before call ing the sta ndard impleme ntatio n.JNI很少對錯誤進行檢查。而錯誤常會導致程序崩潰。An droid為此提供了Ch馳kJNI處理模式,當JAVA虛擬機以及JNIEnv函數(shù)表指針被切換到函數(shù)列表時,該模式會在調(diào)用標準實現(xiàn)之前做岀?系列的附加檢查措施。The additi onal checks in clude:附加的檢查包括:Arrays: attempting to allocate a negative-sized array.數(shù)組

18、:嘗試分配?個長度?為負數(shù)的數(shù)組。Bad poin ters: pass ing a bad jarray/jclass/jobject/jstri ng to a JNI call, or pass ing a NULL poin ter to a JNI call with a nonn ullable argume nt.壞指針:將?個錯誤的jarray/jclass/jobject/jstring傳遞給JNI調(diào)用,或者是帶?個非空參數(shù)將空指針傳遞給JNI調(diào)用。Class names: passing anything but the“ java/lang/String” style o

19、f class name to a JNI call.類名稱:JNI調(diào)用時未采用類似于“ java/lang/String這種格式的類名。Critical calls: making a JNI call between a“ critical”get and its corresponding release.臨界調(diào)用:在 臨界區(qū)'獲取或者釋放的時候進行JNI調(diào)用操作。Direct ByteBuffers: pass ing bad argume nts to NewDirectByteBuffer.直接ByteBuffers :將錯誤的參數(shù)傳遞給NewDirectByteBuffe

20、r函數(shù)。Excepti ons: making a JNI call while there' s an excepti on pending.異常:當發(fā)生異常時進行JNI調(diào)用。JNIE nv* s: using a JNIE nv* from the wrong thread.JNIEnv* s:在錯誤的線程中使用JNIEnv指針。jfieldIDs: using a NULL jfieldID, or using a jfieldID to set a field to a value of the wrong type (trying to assign aStringBuild

21、er to a String field, say), or using a jfieldID for a static field to set an instance field or vice versa, or using a jfieldID from one class with instances of another class.jfieldIDs :使用空的jfieldID,或是通過jfieldID設(shè)置變量值時指定了錯誤的類型(比如說嘗試將String型變量設(shè)置為?個Str in gBuilder類型),?或者是通過ldID將?個靜態(tài)變量設(shè)置為實例變量,反之亦然,還有可能是,

22、通過jfieldID將?個類的對象指定為另外?個類的對象。jmethodIDs: using the wrong kind of jmethodID whe n making a Call* Method JNI call: in correct retur n type, static/ non-www.eoe.c nstatic mismatch, wrong type for' this '(for non-static calls) or wrong class (for static calls).jmethodIDs :運用Call* Method的JNI調(diào)用時,j

23、methodID方法運用錯誤:返回錯誤的類型值,靜態(tài)/非靜態(tài)匹配錯誤, th類型錯誤(當使用非靜態(tài)調(diào)用時)以及錯誤的類定義(使用靜態(tài)調(diào)用時)。Refere nces: using DeleteGlobalRef/DeleteLocalRef on the wrong ki nd of refere nee.引用:調(diào)用DeleteGlobalRef/DeleteLocalRef函數(shù)時使用了錯誤的引用。Release modes: pass ing a bad release mode to a release call (somethi ng other tha n 0, JNI_ABORT,

24、or JNI_COMMIT).Release模式:進行release調(diào)用時使用了錯誤的release模式(即選擇0,JNI_ABORT或者JNI_COMMIT以外的值)Type safety: returni ng an in compatible type from your n ative method (returni ng a Stri ngBuilder from a method declared to retur n a Stri ng, say).類型安全:從你的本地方法中返回了?個不匹配的類型值(比如從?個聲明為g作為返回值的方法中返回?個StringBuilder類型的返回

25、值)UTF-8: pass ing an in valid Modified UTF-8 byte seque nee to a JNI call.UTF-8編碼:將?個無效Modified UTF-8字節(jié)串傳遞給JNI調(diào)用。(Accessibility of methods and fields is still not checked: access restricti ons don't apply to n ative code.)(可訪問的方法禾口變量在此并沒有被檢查:這是因為訪問限制并不適用于本地代碼)There are several ways to enable Che

26、ckJNI.下列方法可以用來使能 CheckJNI 模式。If you ' re using the emulator, CheckJNI is on by defaul如果你用的是模擬器,那么 CheckJNI模式默認已經(jīng)被開啟。If you have a rooted device, you can use the follow ing seque nce of comma nds to restart the run time with CheckJNIenabled:如果你的設(shè)備已經(jīng)獲取root權(quán)限,可以通過以下的命令行來重新啟動運行設(shè)備,使能CheckJNI模式:adb sh

27、ell stopadb shell setprop dalvik.vm.checkj ni trueadb shell startIn either of these cases, you' ll see somethi ng like this in your logcat output whe n the 然后i,i你s可以通過查看設(shè)備啟動運行階段時打印的logcat信息來確認是否開啟該模式。D AndroidRuntime: CheckJNI is ONIf you have a regular device, you can use the followi ng comma n

28、d:如果你手里的機器只是普通發(fā)行版本,你需要使用以下的命令行來開啟模式:adb shell setprop debug.checkj ni 1This won ' t affect already-ru nning apps, but any app lau nched from that point on will have CheckJNI en abled. (Cha ngethe property to any other value or simply rebooti ng will disable CheckJNI aga in.) In this case, youthi

29、s in your logcat output the n ext time an app starts:該方法不會對已經(jīng)運行的應(yīng)用軟件起作用,只能使之后啟動的應(yīng)用軟件帶有CheckJNI模式。(如果將property參數(shù)值作任意修改或者是重啟系統(tǒng)都就能重新禁用CheckJNI模式)。如果你采用這個方法,那么當任何?個應(yīng)用軟件啟動時,你都會在logcat的輸岀窗?看到如下的信息:D Late-enabling CheckJNINative Libraries- 本地庫www.eoe.c nYou can load native code from shared libraries with t

30、he standard System.loadLibrary call. The preferred way to get atyour native code is: 你可以通過標準的System.loadLibrary調(diào)用從共享庫中載?本地代碼。但你還有更好的渠道來獲取本地代碼,方法如下:Call System.loadLibrary from a static class initializer. (See the earlier example, where one is used to calln ativeClass In it.) The argume nt is the &qu

31、ot;un decorated" library n ame, so to load "libfubar.so" you would pass in "fubar".在靜態(tài)類的初始化時調(diào)用 System.loadLibrary。(可以參考之前的例?,比如調(diào)用hativeClass In it函數(shù)時)。將原始”勺庫名作為參數(shù),你將其傳給"fubar"來載? "libfubar.so"動態(tài)鏈接庫。Provide a n ative fun cti on: ji nt JNI_ On Load(JavaVM*

32、vm, void* reserved)提供?個本地函數(shù):int JNI_OnLoad(JavaVM* vm, void* reserved)來實現(xiàn)。In JNI_ On Load, register all of your n ative methods. You should declare the methods "static" so the n ames don't takeup space in the symbol table on the device.在JNI_OnLoad函數(shù)中注冊你所有的本地方法。你可以將所有的方法都聲明為“ static,這樣就

33、不會占用設(shè)備中符號列表上的空間。The JNI_O nLoad fun ction should look somethi ng like this if written in C+:在 C+ 中你可以參考如下方式來構(gòu)造JNI_ On Load 函數(shù):jint JNI_O nLoad(JavaVM* vm, void* reserved) JNIE nv* env; if (vm->GetE nv(rei nterpret_cast<void* * >(&env), JNI_VERSION_1_6) != JNI_OK) return -1; You can also

34、 call Syste m.load with the full path n ame of the shared library. For An droid apps, you may find it useful to get the full path to the applicati on's private data storage area from the con text object.你還可以通過共享庫的完整路徑來調(diào)用System.load。在An droid的應(yīng)用軟件中,你會發(fā)現(xiàn),在對象的上下文中,通過獲取完整路徑來共享應(yīng)用的私有數(shù)據(jù)存儲空間是非常有用的方法。Thi

35、s is the recommended approach, but not the only approach. Explicit registration is not required, nor is it necessarythat you provide a JNI_ On Load fun cti on. You can in stead use "discovery" of n ative methods that are n amed in aspecific way (see the JNI spec for details), though this i

36、s less desirable because if a method sig nature is wrong you won't know about it un til the first time the method is actually used.以上是推薦的方法,但并不是唯?方法。例如,明文注冊并不是必要的環(huán)節(jié)同樣,JNI_ On Load函數(shù)的設(shè)置也不是。你可以通過對本地代碼做特殊命名(參考 the JNI spec這?章的細節(jié))來手動尋找”它們,但是這個方法并不是那么讓?滿意,因為如果你在某個方法的標記上如果岀了錯,除非在第?時間這個方法就被調(diào)用,否則你并將不會意識

37、到它有問題。One other n ote about JNI_ On Load: any Fin dClass calls you make from there will happe n in the con text of the class loader that was used to load the shared library. Normally Fin dClass uses the loader associated with the method at the top of the interpreted stack, or if there isn't one

38、(because the thread was just attached) it uses the "system" class loader. This makes JNI_ On Load a convenient place to look up and cache class object refere nces.關(guān)于JNI_OnLoad的其他備注:你在上文中所調(diào)用的FindClass函數(shù)都可以在共享庫的類裝載器中得到。通常來說,F(xiàn)indClass會使用相關(guān)方法的裝載器來分析棧頂數(shù)據(jù),但如果沒有這樣的裝載器(有可能是已經(jīng)附著到線程上了), 那么它也會使用系統(tǒng)”的類

39、裝載器。這樣做使得JNI_ On Load很容易被找到,而且也能緩存類對象的引用。64-bit Con sideratio ns-64-bit環(huán)境注意事項An droid is curre ntly expected to run on 32-bit platforms. In theory it could be built for a 64-bit system, but that is not agoal at this time. For the most part this isn't somethi ng that you will n eed to worry about

40、 whe n in teract ing with n ative9/12&oeeoe移動開發(fā)者社區(qū)www.eoe.c ncode, but it becomes significant if you plan to store pointers to native structures in integer fields in an object. Tosupport architectures that use 64-bit pointers, you need to stash your native pointers in a long field rather than an

41、 int.An droid當前多運行于32位平臺環(huán)境中。理論上來說,它同樣也能編譯成64位版本,但這并不是最終的解決方案。說,當你使用本地代碼的時候,你并不需要擔心64位的版本問題。但是,假如你打算在某個對象中的integer變量的本地結(jié)構(gòu)體中存儲指針,那么64位版本就會變成為很?的麻煩。因此,為了能夠在64位架構(gòu)下使用指針,你必須將你的本地指針存儲為long形而非int型。不支持Un supported Features/Backwards Compatibility的特征/向前兼容性All JNI 1.6 features are supported, with the following

42、 exception:除了以下情況外,所有的 1.6版本的 JNI 的特性都被支持:Defin eClass is not impleme nted. An droid does not use Java bytecodes or class files, so pass ing in binary class data does n't work.Defin eClass方法還沒有被實現(xiàn)。An droid當前沒有使用JAVA比特編碼或者類,所以是無法傳遞給它們?進制類文件For backward compatibility with older An droid releases,

43、you may n eed to be aware of:對早期 An droid 發(fā)布版本的向前兼容性,你需要注意以下?點:Dyn amic lookup of n ative fun cti ons動態(tài)查找本地函數(shù) :Until An droid 2.0 (Eclair), the '$' character was n ot properly con verted to "_00024" duri ng searchesfor method n ames. Work ing arou nd this requires using explicit re

44、gistrati on or moving the n ative methods out of innerclasses.:到Android2.0 ( Eclair )版本為止,在搜索方法名稱時,字符還不能夠被準確轉(zhuǎn)換為"_00024"。為了解決這個問題,你可以使用明文注冊或者是將本地方法從內(nèi)部類中移岀。Detach ing threads分離線程 :Un til An droid 2.0 (Eclair), it was not possible to use a pthread_key_create destructor fun cti on to avoid the

45、"thread must be detached before exit" check. (The run time also uses a pthread key destructor fun cti on, so it'd be arace to see which gets called first.):到Android2.0 ( e cla)r 版本為止,利用 pthread_key_create 析構(gòu)函數(shù)來免除 線程在退岀時先斷開”的檢查是無法做到的(運行時同樣會用到pthread關(guān)鍵析構(gòu)函數(shù),所以看誰能更快的取得這個函數(shù),這是個比賽)。Weak glob

46、al refere nces弱全局引用 :Un til An droid 2.2 (Froyo), weak global refere nces were not impleme nted. Older vers ions will vigorouslyreject attempts to use them. You can use the An droid platform vers ion con sta nts to test for support.:到 Android2.2 ( Froyo )版本為止,弱全局引用還不能實現(xiàn)。舊版本不遺余?的拒絕使用該功的平餡可以用版本常數(shù)來測試是否

47、支持這個功能。:Until An droid 4.0 (Ice Cream San dwich), weak global refere nces could only be passed to NewLocalRef,NewGlobalRef, and DeleteWeakGlobalRef. (The spec stro ngly en courages programmers to create hard refere nces toweak globals before doing any thi ng with them, so this should not be at all l

48、imit in g.):而到 An droid4.0(Ice Cream San dwich)版本為止,弱全局引用也僅能在NewLocalRef, NewGlobalRef, 以及DeleteWeakGlobalRef ?個函數(shù)中實現(xiàn)(規(guī)范中鼓勵程序員在引用操作之前創(chuàng)造強(hard )引用,從而代替弱全局引用,因而弱全局引用并未被完全限制使用):From An droid 4.0 (Ice Cream San dwich) on, weak global refere nces can be used like any other JNI refere nces.www.eoe.c n:但從A

49、n droid4.0(lce Cream San dwich)版本起,弱全局引用可以在除了JNI引用之外的所有地方使用了。Local refere nces局部引用 :Un til An droid 4.0 (Ice Cream San dwich), local refere nces were actually direct poin ters. Ice Cream San dwichadded the in directi on n ecessary to support better garbage collectors, but this means that lots of JNI

50、 bugs are undetectable on older releases. See JNI Local Reference Changes in ICS for more details.:到 An droid 4.0 (Ice Cream San dwich)版本為止,所謂的本地引用都是指直接指針。Ice Cream San dwich 版本為了更好進行垃圾回收,添加間接指針機制,但是這樣?來也就意味著 ?量的的BUG在舊版本中無法被發(fā)現(xiàn)了。具體的細節(jié)可以參考 JNI Local Refere nce Cha nges in ICS?節(jié)。Determi ning refere nce

51、 type with GetObjectRefType通過GetObjectRefType確認引用類型:Un til An droid 4.0 (Ice Cream San dwich), as a con seque nce of the use of direct poin ters (see above), it was impossible to impleme nt GetObjectRefType correctly .In stead we used a heuristic that looked through the weak globals table, the argum

52、ents, the locals table, and the globals table in that order. The first time it found your direct pointer, it would report that your reference was of the type it happened to be examining. This meant, for example, that if you called GetObjectRefType on a global jclass that happened to be the same as t

53、he jclass passed as an implicit argume nt to your static n ative method, you'd get JNILocalRefType rather tha n JNIGlobalRefType.:到 An droid 4.0 (Ice Cream San dwich)版本為止,由于?直使用直接指針的緣故(見上),導致系統(tǒng)無法實現(xiàn)GetObjectRefType方法。我們只能探索性的使用弱全局列表,參數(shù),本地列表以及全局列表。首先它會找到你的直接指 針,然后報告你的引用剛好是可以被驗證的類型。這也就是說,如果你在?c個全中調(diào)

54、用GetObjectRefType函數(shù),那么與jclass將?個隱形參數(shù)傳給靜態(tài)本地方法的效果是?樣的,此時你獲得的其實是JNILocalRefType的值,而非JNIGlobalRefType 的。FAQ: Why do I get Un satisfiedLi nkError?-FAQ:為什么我得到了 UnsatisfiedLinkError 錯誤?When work ing on native code it's not un common to see a failure like this:在本地代碼環(huán)境下,岀現(xiàn)如下的錯誤是很常見的:java .lang.Un satisfi

55、edL in kError: Library foo not foundIn some cases it means what it says the library was n't found. In other cases the library exists but could n't beope ned by dlope n( 3), and the details of the failure can be found in the excepti on's detail message.有時候,這個問題的原因就像它的字面意思?樣一這個庫找不到了。而還有些情況

56、是這個庫文件存在,但是你無法通過dlopen(3)函數(shù)打開它,關(guān)于該錯誤問題的細節(jié)你可以在異常的詳細消息中進行查詢。Common reasons why you might encounter "library not found" exceptions:對于你遇到的異常 library not found" 常見的原因是:The library does n't exist or isn't accessible to the app. Use adb shell ls -l to check its prese nce and permissi

57、 ons.該庫文件不存在,或者是無法被應(yīng)用所訪問。使用adb shell ls -l命令來檢查它的狀態(tài)以及訪問權(quán)限。The library was n't built with the NDK. This can result in depe nden cies on fun cti ons or libraries that don't exist on the device.該庫文件還沒有被NDK編譯出來。這會導致依賴函數(shù)或者庫文件在設(shè)備上不存在。Another class of UnsatisfiedLinkError failures looks like:另夕卜 ?類

58、錯誤UnsatisfiedLinkError 表示如下:java .lang.Un satisfiedL in kError: myfu nc at Foo.myfu nc(Native Method) at Foo.ma in(F oo.java:10)In logcat, you'll see: 在logcat 中,你可以看到:W/dalvikvm( 880): No implementation found for native LFoo;.myfunc ()VThis means that the run time tried to find a matchi ng method but was un successful. Some com mon reas ons for thisare:這是指運行時嘗試去尋找?個匹配的方法但是失敗了。這個問題的原因有可能是:The library isn't gett ing loaded. Check the logcat output for messages about library loadi ng.該庫文件無法被載?。請檢查庫文件載?過程中的ogcat輸出消息。The method isn't being found due to a n

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論