天天看點

Android中JNI的了解與使用

基礎知識

JNI(Java Native Interface,JAVA原生接口)

使用JNI可以使Java代碼和其他語言寫的代碼(如C/C++代碼)進行互動。

問:為什麼要進行互動?

|-  首先,Java語言提供的類庫無法滿足要求,且在數學運算,實時渲染的遊戲上,音視訊處理等方面上與C/C++相比效率稍低。

|-  然後,Java語言無法直接操作硬體,C/C++代碼不僅能操作硬體而且還能發揮硬體最佳性能。

|-  接着,使用Java調用本地的C/C++代碼所寫的庫,省去了重複開發的麻煩,并且可以利用很多開源的庫提高程式效率。

C語言常見術語:

庫函數:printf      scanf       malloc free

|-  為了代碼重用,在C語言中提供了一些常用的、用于執行一些标準任務(如輸入/出)的函數,這些函數事先被編譯,并生成目标代碼,然後将生成的目标代碼打包成一個庫檔案,以供再次使用。庫檔案中的函數被稱為庫函數,庫檔案被稱為函數庫。

|-  在Windows中C語言庫函數中的中間代碼都是以.obj為字尾的,Linux中是以 .o為字尾。

提示:單個目标代碼是無法直接執行的,目标代碼在運作之前需要使用連接配接程式将目标代碼和其他庫函數連接配接在一起後生成可執行的檔案。 Windows下.dll的檔案 , linux下 .so .a的檔案.

頭檔案:xxx.h

|-  頭檔案中存放的是對某個庫中所定義的函數、宏、類型、全局變量等進行聲明,它類似于一份倉庫清單。若使用者程式中需要使用某個庫中的函數,則隻需要将該庫所對應的頭檔案include到程式中即可。

   |-  頭檔案中定義的是庫中所有函數的函數原型。而函數的具體實作則是在庫檔案中。

   |-  簡單的說:頭檔案是給編譯器用的,庫檔案是給連接配接器用的。

|-  在連結器連接配接程式時,會依據使用者程式中導入的頭檔案,将對應的庫函數導入到程式中。頭檔案以.h為字尾名。

函數庫:

|-  動态庫:在編譯使用者程式時不會将使用者程式内使用的庫函數連接配接到使用者程式的目标代碼中,隻有在運作時,且使用者程式執行到相關函數時才會調用該函數庫裡的相應函數,是以動态函數庫所産生的可執行檔案比較小。

|-  靜态庫:在編譯使用者程式時會将其内使用的庫函數連接配接到目标代碼中,程式運作時不再需要靜态庫。使用靜态庫生成可執行檔案比較大。

在Linux中:

|-  靜态庫命名一般為:lib+庫名+.a 。

|-  如:libcxy.a 其中lib說明此檔案是一個庫檔案,cxy是庫的名稱,.a說明是靜态的。

|-  動态庫命名一般為:lib+庫名+.so 。.so說明是動态的。

交叉編譯:

|-  将中間代碼連接配接成目前計算機可執行的二進制程式時,連接配接程式會根據目前計算機的CPU、作業系統的類型來轉換。

根據運作的裝置的不同,可以将cpu分為:

|-  arm結構 :主要在移動手持、嵌入式裝置上。

|-  x86結構 : 主要在桌上型電腦、筆記本上使用。如Intel和AMD的CPU 。

若想在使用了基于x86結構CPU的作業系統中編譯出可以在基于arm結構CPU的作業系統上運作的代碼,就必須使用交叉編譯。

交叉編譯:在一個平台下編譯出在另一個平台中可以執行的二進制代碼。Google提供的NDK就可以完成交叉編譯的工作。

NDK全稱:Native Development Kit 。

|-  NDK是一系列工具的集合,它有很多作用。

   |-  首先,NDK可以幫助開發者快速開發C(或C++)的動态庫。

   |-  其次,NDK內建了交叉編譯器。使用NDK,我們可以将要求高性能的應用邏輯使用C開發,進而提高應用程式的執行效率。

NDK工具必須在Linux下運作,它可以在linux環境下編譯出可以在arm平台下運作的二進制庫檔案。

使用JNI技術,其實就是在Java程式中,調用C語言的函數庫中提供的函數,來完成一些Java語言無法完成的任務。由于Java語言和C語言結構完全不相同,是以若想讓它們二者互動,則需要制定一系列的規範。JNI就是這組規範,此時    Java隻和JNI互動,而由JNI去和C語言互動。

JNI技術分為兩部分:Java端和C語言端。且以Java端為主導。

|-  首先,Java程式員在Java端定義一些native方法,并将這些方法以C語言頭檔案的方式提供給C程式員。

|-  然後,C程式員使用C語言,來實作Java程式員提供的頭檔案中定義的函數。

|-  接着,C程式員将函數打包成一個庫檔案,并将庫檔案交給Java程式員。

|-  最後,Java程式員在Java程式中導入庫檔案,然後調用native方法。

在Java程式執行的時候,若在某個類中調用了native方法,則虛拟機會通過JNI來轉調用庫檔案中的C語言代碼。提示:C代碼最終是在Linux程序中執行的,而不是在虛拟機中。

問題:在Android中可執行的檔案,在Linux中一定可以執行嗎?

轉載于:https://blog.51cto.com/tlwnet/1671471