首先介紹一下JNI設計的目的:
JNI是Java Native Interface的縮寫:
The standard Java class library may not support the platform-dependent features needed by your application.
You may already have a library or application written in another programming language and you wish to make it accessible to Java applications
you may want to implement a small portion of time-critical code in a lower-level programming language,such as assembly, and then have your Java application call these functions.
Android系統中使用JNI原因
Android上層使用Java語言來開發應用程式,而且在Android系統架構圖中可以看到,Android framework層也都是嚮應用開發人員提供Java API,但是所有的本地庫都使用了C/C++來實現,這就需要使用JNI方式向Java提供介面,是java層的介面能調用本地的具體實現。
JNI架構
Android framework層中的API大部分調用了native方法,這些方法也都由本地代碼來實現,然後註冊到系統中。註冊過程需要使用Dalvik中的一個工具庫nativehelper,該庫的主要用於註冊Java本地調用的函數(即通過JNI方式向上層提供介面)。
實現nativehelper庫的原始碼位於“dalvik\libnativehelper”目錄中,最終將被編譯為libnativehelper.so動態連結程式庫。通常使用JNI方式時需要使用該庫,其主要標頭檔如下:
dalvik\libnativehelper\include\nativehelper\jni.h(基於JNI標準的標頭檔)
dalvik\libnativehelper\include\nativehelper\JNIHelper.h(提供JNI註冊功能的標頭檔)
具體的JNI代碼的實現主要位於frameworks\base\core\jni\目錄中,實現了Android API的大部分功能,最終將被編譯為libandroid_runtime.so動態連結程式庫,放置在out目錄下的\system\lib目錄中。
JNI的實現
實際上JNI需要實現的主要內容有兩個:首先將java、代碼中聲明的原生方法在本地註冊。然後註冊到系統中。
Q:
在我們編寫JNI的時候,很有可能導致系統啟動的過程中,啟動失敗。分析主要的原因有兩個方面:一是我們找不到class,另一種是我們找不到nativemethod。這兩種情況都是我們在編寫檔案的時候的java和cpp的函數或者路徑名稱不匹配造成的。因此在此種情況下我們一定要仔細檢查一邊。此前出現問題的時候,我還白白的認為是android有什麼玄機導致我們不能修改和添加檔案和函數。後來發現是自己的粗心造成的。