我們已經介紹了如何通過 .NET 綁定 iOS 原?庫 ,本篇開始介紹?下如何通過 .NET 綁定 Android 原?庫。
Android的庫
Android 的庫以 .jar 做打包, 通過?具你可以將多個 .jar 完成綁定,然后通過 C# 調?原?的 Java 庫。對?起 iOS , Android 的庫綁定簡單很多。
從上圖可以看到 Xamarin.Android / .NET for Android 通過使?托管可調?包裝器 (MCW) 實現綁定。MCW 是?個 JNI 橋,在托管代碼需要調? Java 代碼時會使?它。托管可調?包裝器還?持對 Java 類型進??類化以及覆蓋 Java 類型的虛擬?法。同樣,每當 Android 運?時 (ART) 代碼需要調?托管代碼時,它都會通過另?個稱為 Android 可調?包裝器 (ACW) 的 JNI 橋來實現。
創建?個 Android 原?庫綁定項?
通過命令?創建?個 Android 原?庫綁定項?
dotnet new android-bindinglib -o Droid.AMap
進?該項?我們看看?件結構
項???有 Transforms ?件夾有對應的三個 xml ?件,分別是 EnumFields.xml ,EnumMethods.xml , Metadata.xml , 各?作?如下 :
MetaData.xml?– 允許對最終 API 進?更改,例如更改?成的綁定的命名空間。
EnumFields.xml?– 包含 Java int 常量與 C# enums 之間的映射。
EnumMethods.xml?– 允許將?法參數和返回類型從 Java int 常量更改為 C# enums
其中 MetaData.xml ?件是這些?件中的最常?的導?,因為它允許對綁定進??般?途的更改,例如:
重命名命名空間、類、?法或字段,使其遵循 .NET 約定。
刪除不需要的命名空間、類、?法或字段。
將類移到不同的命名空間。
添加其他?持類以使綁定的設計遵循 .NET 框架模式。
01
把 jar ?件添加到綁定項?
在項?在項?中添加 Jars ?錄 ,把?德地圖的 jar 包添加到該?錄下 ,并把 arm64-v8a ,armeabi-v7a ,x86_64 ,這三個?錄添加進來:
添加完成后,修改 .csproj ?件
<Project?Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net6.0-android</TargetFramework><SupportedOSPlatformVersion>21</SupportedOSPlatformVersion><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings></PropertyGroup><ItemGroup><EmbeddedNativeLibrary Include="Jars\arm64-v8a\libAMapSDK_MAP_v9_3_0.so" /><EmbeddedNativeLibrary Include="Jars\armeabi-v7a\libAMapSDK_MAP_v9_3_0.so" /><EmbeddedNativeLibrary Include="Jars\x86_64\libAMapSDK_MAP_v9_3_0.so" /> </ItemGroup><ItemGroup><TransformFile Include="Transforms\Metadata.xml" /><TransformFile Include="Transforms\EnumFields.xml" /><TransformFile Include="Transforms\EnumMethods.xml" /></ItemGroup><ItemGroup><EmbeddedJar Include="Jars\AMap3DMap_9.3.0_AMapSearch_9.2.0_AMapLocation_6.1.0_20220608.jar" /></ItemGroup>
</Project>
這樣就把項?添加好了,沒有像 iOS 原?庫綁定那么繁瑣。然后編譯?下 ,凡爾賽 + 星??海了。
02
排雷工作
看?這么多錯,真的要考慮?下是不是放棄,其實這也?常治愈,我們逐個來排雷。
*'PoiCreator' does not implement interface member?'IParcelableCreator.NewArray(int)'.
'PoiCreator.NewArray(int)' cannot implement?'IParcelableCreator.NewArray(int)'
錯誤對應的是這個?法 ,實際就是返回類型出錯了,我們先根據源?件看看 path 路徑就可以解決
// Metadata.xml XPath method reference: path="/api/package[@name='com.amap.api.maps.model']/class[@name='PoiCreator']/method[@name='newArray' and count(parameter)=1 and parameter[1][@type='int']]"
[Register ("newArray", "(I)[Lcom/amap/api/maps/model/Poi;", "GetNewArray_IHandler")]
public virtual unsafe global::Com.Amap.Api.Maps.Model.Poi[]? NewArray (int p0)
{const string __id = "newArray.(I)[Lcom/amap/api/maps/model/Poi;";try {JniArgumentValue* __args = stackalloc JniArgumentValue [1];__args [0] = new JniArgumentValue (p0);var __rm = _members.InstanceMethods.InvokeVirtualObjectMethod (__id, this, __args);return (global::Com.Amap.Api.Maps.Model.Poi[]?) JNIEnv.GetArray (__rm.Handle, JniHandleOwnership.TransferLocalRef, typeof (global::Com.Amap.Api.Maps.Model.Poi));} finally {}}
確認好后,需要在 Metadata.xml 做添加
<attr?path="/api/package[@name='com.amap.api.maps.model']/class[@name='PoiCreator']/method[@name='newArray'?and?count(parameter)=1?and?parameter[1][@type='int']]"?name="managedReturn">Java.Lang.Object[]</attr>
*The type 'AMap' already contains a definition for 'MarkerDragEnd'
這個是重復定義導致的,只需要添加如下代碼刪除就可以了,如
<remove-node?path="/api/package[@name='com.amap.api.maps']/interface[@name='AMap.OnCameraChangeListener']"?/>
*'BusLineSearch': member names cannot be the same as their enclosing type
重命名導致的錯誤 ,把名字修改?下即可,如
<attr?path="/api/package[@name='com.amap.api.services.busline']/class[@name='BusLineSearch']"?name="managedName">AmapBusLineSearch</attr>
*cannot change access modifiers when overriding 'protected'
重載的時候出現權限問題,這個時候你需要的是把權限修正好,如
<attr?path="/api/package[@name='com.amap.api.maps.model']/class[@name='PolygonOptions']/method[@name='getUpdateFlags'?and?count(parameter)=0]"name="visibility">protected</attr>
解決上述的所有問題,基本上就可以治愈了,當編譯通過?刻你會?常興奮
找個 .NET for Android 項?看看

?家可以去我的 GitHub 下載該示例
https://github.com/kinfey/AMapMAUIControls/tree/main/samples/Droid.Bindings
小結
Android 的原?綁定? iOS 的簡單得多,所以更容易??。希望各位?伙伴能多動?,有時候也是?個很好的體驗。經過兩篇?章的學習,相信?家也掌握了如何? .NET 綁定 iOS 和 Android 的原?庫了。最后?篇?章我們來討論下如何做?個適配 MAUI 的原?控件。
*相關資料
1. 通過 Microsoft Docs 了解 MAUI?
https://aka.ms/Docs.MAUI
2. 通過 Microsoft Learn 學習 MAUI?
https://aka.ms/Learn.MAUI
3.使??德地圖 SDK for Android 請訪問
https://developer.amap.com/api/android-sdk/gettingstarted
4.了解 Android 原?庫綁定的內容,請訪問 https://docs.microsoft.com/enus/xamarin/android/platform/binding-java-library/
CA周記往期回顧:
更多原創文章與資源共享
請關注Kinfey Techtalk