系結 Java 連結庫
Android 的第三方連結庫生態系統非常龐大。 因此,使用現有的 Android 連結庫通常比建立新的連結庫有意義。
適用於 Android 的 .NET 可讓您使用 系結連結庫 來執行此動作,以使用 C# 包裝函式自動包裝連結庫,以便您可以透過 C# 呼叫叫用 Java 程式代碼。
這是使用 Managed 可呼叫包裝函式 (MCW) 實作的。 MCW 是 JNI 網橋,用於 Managed 程式代碼需要叫用 Java 程式代碼時。 Managed 可呼叫包裝函式也支援子類別化 Java 類型,以及在 Java 類型上覆寫虛擬方法。 同樣地,每當 Android 執行時間 (ART) 程式代碼想要叫用 Managed 程式代碼時,它就會透過另一個稱為 Android 可呼叫包裝函式的 JNI 網橋來叫用 Managed 程式代碼。 下圖說明此架構:
系結連結庫是包含 Java 類型的 Managed 可呼叫包裝函式的元件。 例如,以下是我們想要包裝在系結庫中的 Java 類型 MyClass
:
package com.contoso.mycode;
public class MyClass
{
public String myMethod (int i) { ... }
}
針對包含MyClass
的.jar產生系結庫之後,我們可以從 C# 將它具現化並呼叫方法:
var instance = new MyClass ();
string result = instance.MyMethod (42);
若要建立此系結連結庫,您可以使用適用於 Android Android Java 系結連結庫 的 .NET 範本。 產生的系結專案會使用MCW類別、.jar.aar/檔案,以及內嵌在其中之Android Library專案的資源,建立 .NET 元件。 藉由參考產生的系結連結庫元件,您可以在 .NET for Android 專案中重複使用現有的 Java 連結庫。
當您在系結連結庫中參考類型時,必須使用系結連結庫的命名空間。 一般而言,您會在 C# 原始程式檔頂端新增 using
指示詞,這是 Java 套件名稱的 .NET 命名空間版本。 例如,如果系結 .jar 的 Java 套件名稱如下:
com.contoso.package
然後,您會將下列 using
語句放在 C# 來源檔案頂端,以存取系結 .jar 檔案中的類型:
using Com.Contoso.Package;
系結現有的 Android 連結庫時,必須記住下列幾點:
連結庫是否有任何外部相依性? – Android 連結庫所需的任何 Java 相依性都必須透過 NuGet 套件或 AndroidLibrary 包含在 .NET for Android 專案中。 任何原生元件都必須新增至系結專案做為 AndroidNativeLibrary。
Android 連結庫的目標 Android API 版本為何? – 無法「降級」Android API 層級;請確定適用於 Android 的 .NET 系結專案是以與 Android 連結庫相同的 API 層級(或更高層級)為目標。
將 Java API 調整為 C⧣
適用於 Android 系結產生器的 .NET 將會變更一些 Java 慣用語和模式,以對應至 .NET 模式。 下列清單描述 Java 如何對應至 C#/.NET:
Java 中的 Setter/Getter 方法是 .NET 中的 Properties。
Java 中的欄位 是 .NET 中的屬性 。
Java 中的接聽程式/接聽程式介面 是 .NET 中的事件 。 回呼介面中方法的參數將由子類別表示
EventArgs
。Java 中的靜態巢狀類別是 .NET 中的巢狀類別。
Java 中的 Inner 類別是巢狀類別,具有 C# 中的實例建構函式。
在系結中包含原生連結庫
在系結 Java 連結庫時,可能需要在 .NET for Android 系結專案中加入 .so 連結庫。 當包裝的 Java 程式代碼執行時,Android 的 .NET 將無法進行 JNI 呼叫,而且錯誤訊息 java.lang.UnsatisfiedLinkError:找不到原生方法: 將會出現在應用程式的 logcat out 中。
修正此問題的作業是手動載入 .so 連結庫,並呼叫 Java.Lang.JavaSystem.LoadLibrary
。 例如,假設 .NET for Android 專案已將共用連結庫libpocketsphinx_jni.so 包含在系結專案中,且具有 AndroidNativeLibrary 的建置動作,下列代碼段(在使用共用連結庫之前執行)會載入 .so 連結庫:
Java.Lang.JavaSystem.LoadLibrary("pocketsphinx_jni");
系結案例
下列系結案例指南可協助您系結 Java 連結庫(或連結庫),以納入您的應用程式: