2012-10-05 36 views
0

介紹:我有使用Java(JNI)包裝本地庫(C++)。庫引擎是cpu密集型的,我們不希望鏈接這個庫的多個應用程序同時運行,並且複雜的對象應該由lib引擎返回。的Android庫工程

問題:設計這樣一個Android庫的最佳方式是什麼?

到目前爲止,我能找到的只是找到2個有價值的例子:OpenCV的經理Connectbot的ssh-agent

我能想到的幾個解決方案:

  • 解決方案1 ​​:請一個包裝庫功能的(綁定或AIDL)服務。 (如果服務運行在自己的空間或者應用程序的空間中,如果它在不同的應用程序空間(System.load("/data/data/com.company.myLib/lib.so"))如何加載本地lib如何在AIDL中返回複雜的對象?)。這應該是Connectbot的方式。

  • 解決方案2:劃分的lib分成以下兩個部分:

    1. 一個獨立的包,它保持了原生庫+經理服務
    2. 一個Android的lib項目僅包含Java包裝哪些用戶可以用來構建他們的應用程序。

    這應該是OpenCV的經理的方式。我不清楚細節,但這種方式不需要服務來連接,只需import com.company.myLib.LibWrapper。另一方面,LibWrapper類應該執行System.load("/data/data/com.company.myLib/lib.so")。正確?

我會親自去解決2.不幸的是Android是一個新的土地並沒有很多車型尚未就如何開發庫。有沒有其他更好的解決方案?還有其他的考慮嗎?

+0

在我看來,決定性的問題是你想要爲你的圖書館提供什麼樣的交付模式。它會被使用它的應用程序更新,還是可以單獨下載和升級? –

+0

@Alex Cohn:可能獨立升級/下載。好的考慮btw! – Sdra

回答

2

考慮以下方案:您打造一個「空」的應用程序不包含任何活動,沒有設置 - 僅清單,圖標爲「管理應用程序」列表中,並且由系統中安裝了本地庫/數據/ data//lib目錄。

此機庫可以,但沒有暴露JNI功能。在一個典型的情況下,這個lib將是一個開源的LGPL庫的簡單端口 - 例如libdmtx.so。

「客戶機」的應用程序將調用的LoadLibrary()爲「外部」 LIB,之後它將調用通常負載()其JNI包裝。此lib具有將Java方法轉換爲外部庫的公共C API的唯一目的。

的JNI封裝和相應的Java類可以被分佈作爲一個.jar或作爲源,它們不是由外部IIb的LGPL許可約束。

這樣的方案是,恕我直言,唯一的方法來確保Android上的LGPL符合性:任何人都可以從開放源代碼重新編譯「外部」庫,將其打包爲一個「空白」應用程序並將其安裝到他們的設備上。

關於您對lib的併發訪問的擔心,我真的懷疑它是如此重要:高端設備有四個內核,每個內核比一個內核更便宜。 OTOH,很容易使用Linux同步方法,例如命名管道,以跟蹤活動實例。

+0

分析良好,+1!進一步的問題:調用System.load加載另一個apk的本地庫是否合法? – Sdra

+0

你是什麼意思的「合法」?我不認爲這種技術可以保證所有未來的版本和Android的風格。 –

+0

Afaik,apk是獨立的「沙箱」,每個沙箱都有自己的用戶權限。在設備上,我有/data/data/com.my.app/lib設置了讀取權限,因此我可以從另一個使用不同用戶標識的應用程序加載其中包含的庫。但這是否適用於所有的Android設備/環境? – Sdra