2012-05-07 62 views
1

我正在編寫一個Android應用程序。我正在使用JNI在C++中實現一些應用程序。有沒有一種方法可以將JNI(C++)代碼與Java Android代碼完全分開?像創建一個JNI項目什麼的?因爲我的C++代碼將成爲我將在另一個應用中使用的一個小型庫。我試圖創建一個C++項目,但我不能用ndk-build進行編譯。如何將JNI部分從Android應用程序中分離出來?

回答

0

如果您在C++代碼中使用JNI,那麼它將綁定到Android,並且它必須是具有正確定義的Android.mk,Application.mk(可選)的Android項目。

如果你沒有在你的代碼中使用JNI API,比如你想創建一個通用庫,你可以編寫你的C++代碼,編譯它,照常測試,不需要ndk-build。當你完成對庫的編碼時,將代碼構建爲一個靜態庫,並且當你想在你的Android項目中使用這個靜態庫時,在你想要使用的靜態庫中的函數中編寫一些JNI包裝,圖書館在Android.mk,這樣的事情:

include $(CLEAR_VARS) 
LOCAL_MODULE := libgeneric 
LOCAL_SRC_FILES := prebuilt/libgeneric.a 
include $(PREBUILT_STATIC_LIBRARY) 
+0

只是不正確。儘管從類似Android項目結構的東西中運行ndk-build是最容易的,但這不是構建jni庫的唯一方法。或者,您可以擁有一個只包含jni代碼的虛擬android項目結構 - 實際的應用程序可以在其他地方。另外,這裏的「靜態庫」註釋對靜態庫lib必須用Android編譯器**(例如ndk's)構建的事實有點不清楚。首先爲其他東西(比如開發機器)構建它是有用的,但它必須重新編譯以針對每個感興趣的Android ABI。 –

1

實際上,束在Java和本地代碼之間是相當寬鬆的,因爲它是在運行時的方法的名稱來完成。

NDK只是C編譯器的特殊環境和庫。必須生成一個合適的動態庫文件,但這可以使用ndk腳本,使用ndk生成的「獨立工具鏈」完成,甚至可以在java項目構建之前(或之後)完成,在另一臺機器上完成,等等。

通常,.so動態庫被拷貝到應用程序項目樹中的適當位置,這樣它將最終打包在.apk文件中並安裝在可由System.loadLibrary自動發現的設備上() 方法。但是你可以將它插入到另外完成的.apk文件中(這是一個帶有特殊對齊和jarsigner簽名的zip文件)。但即使.pak實際上並不是將其交付給設備的唯一方式(儘管它是唯一推薦的方式) - 庫也可以存儲在諸如應用程序的私人文件夾之類的位置,並使用System.load加載( ),它採用完整的路徑名而不是庫名。

hotverspicy的確有一個問題,即java代碼需要一個本地方法「聲明」,以實現jni庫中實現的內容,並且這需要與本地函數實現名稱中編碼的實際包名稱相匹配。然而,這個包的名稱不一定與其他的java代碼相同 - 它可能是可重用的C/C++庫的通用類型,它只需要在匹配的java包中包含一個簡短匹配的java類文件名稱。

但除了Neevek使用一個本地lib與另一個本地lib交互的想法外,在編譯時只需建立一個關聯,也可以使用對象工廠機制在運行時掛接任意本地函數 - 請參閱C/C++ Reflection and JNI - A method for invoking native code which hasn't been written yet的相關答案

相關問題