2012-02-01 58 views
1

我有一個與cpp ndk lib的Android應用程序。該庫基於名爲Main的對象。 Main.cpp的:NDK架構

static Main * instance; 
Java_my_package_MainService_initMain() 
{ 
    instance = new Main(); //OK 
} 

應用的JAVA部分啓動的服務,初始化主CPP對象的服務,然後開始一個活動(我希望服務在後臺做的東西,而有時會出現運行是用戶的UI)。當我從新活動中調用lib時,Main對象爲null。

我在做什麼錯? 謝謝,那鴻

+0

我想出了一些東西:服務啓動活動後,垃圾收集器清理它並卸載lib。所以我想真正的問題是,爲什麼服務不能繼續運行? – nmnir 2012-02-01 13:59:38

+0

該分析不正確。垃圾收集器不會卸載JNI庫,實際上目前你甚至不能明確地卸載它們。但是,如果進程終止並被替換,您可能會得到一個新的進程,它從未加載過庫,或者加載了庫,但從未被告知初始化您似乎試圖用作單例的靜態變量。 – 2014-04-11 20:00:47

回答

2

我不知道這是否是一個很好的解決方案,下面是我在做什麼。

JNIEXPORT jint JNICALL Java_my_package_MainService_initMain() 
{ 
    Main *instance = new Main(); 
    return (int)instance; 
} 

我將對象(對象只是一個指針)轉換爲一個int並將其返回給java。 然後java把對象發送給所有的JNI函數。

+0

這種方法看起來像我用過的 – 2013-08-18 08:15:06

0

你需要保持引用創建使用NDK中有點不同方式的Java類。

首先創建一個Java類(我們稱之爲主),那麼本機的功能鏈接到一個實例方法(非靜態)。

然後調用從主要的構造函數的本地方法。

在Java應用程序中創建一個靜態參考其他地方,並對其進行初始化「新的Main();」。

現在您參考保持,因此Java類,無法卸載,因此LIB就不會被自動卸載。

0

我決定實現在擴展
android.app.Application我的應用程序類調用System.load。
這是一個保證在整個應用程序生命週期中存在的對象。
這樣就不會卸載dll或重新加載,當然會造成不必要的開銷。
而且由於堆 - 處理(Java的面)是相當複雜的(記得
「機器人:launchMode」屬性,它一定程度上這不會忽略的問題),
我選擇寧願留在系統處理這類的dll - 同治。