IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 做?个?德地图的 iOS / Android MAUI 控件(下) -> 正文阅读

[移动开发]做?个?德地图的 iOS / Android MAUI 控件(下)

我们已经介绍了如何通过 .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 框架模式。?

▌把 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\armeabiv7a\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> <EmbeddedJarInclude="Jars\AMap3DMap_9.3.0_AMapSearch_9.2.0_AMapLocation_6.1.0_20220608.jar" /> </ItemGroup></Project>

这样就把项?添加好了,没有像 iOS 原?库绑定那么繁琐。然后编译?下 ,凡尔赛 + 星??海了

排雷工作

看?这么多错,真的要考虑?下是不是放弃,其实这也?常治愈,我们逐个来排雷。

  • '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 (intp0){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 做添加?

<attrpath="/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-nodepath="/api/package[@name='com.amap.api.maps']/interface[@name='AMap.OnCameraChangeListener']" />
  • 'BusLineSearch': member names cannot be the same as their enclosing type?

重命名导致的错误 ,把名字修改?下即可,如?

<attrpath="/api/package[@name='com.amap.api.services.busline']/class[@name='BusLineSearch']" name="managedName">AmapBusLineSearch</attr>
  • cannot change access modifiers when overriding 'protected'?

重载的时候出现权限问题,这个时候你需要的是把权限修正好,如

<attrpath="/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 是开发跨平台应?的解决?案 ,? C# 可以直接把 iOS , Android , Windows , macOS , Linux ,Tizen 等应?开发出来。那我们在这个框架除了?底层?定义的 UI 控件外,如果我们要?如?德地图这样的 第三?控件,要如何做呢?接下来我就和?家介绍?下。

如果你还没有学习原?库绑定的知识,可以到以下链接学习相关内容:

在上?两个例?中我们学习到把原??德的 iOS / Android SDK 绑定,也? .NET for iOS 和 .NET for Android 进?了调?。但要? MAUI 就意味着调??式改变, ?次性编写多平台使?。要实现这个效果,先看看 MAUI 的基础架构。

我们可以清楚看到, MAUI 除了公?的 xmal ?件外, 实际上也把特定平台的?些设定放置到 Platforms 的?件夹内, Platforms 的??件夹就是对应的平台。我们知道可以根据不同平台去渲染平台界?。这就是我们 常说的?定义平台控件了。?

在前?部分我们也提到了 MAUI 采? Handler 模式去设定平台界?。如果我们要实现?个?德地图的 MAUI 控件,具体的架构是这样的

我们需要去创建如上图的?个结构,我们需要为 AMap 添加?个共享?件 AMap.shared.cs ,这个?件 AMapHandler 继? ViewHandler。

 public interface IAMap : IView { } public class AMap : View, IAMap { } partial class AMapHandler { public static IPropertyMapper<AMap, AMapHandler> MapMapper = newPropertyMapper<AMap, AMapHandler>(ViewHandler.ViewMapper) { }; public AMapHandler() : base(MapMapper) { } }

然后在 Platforms 下的 Android 和 iOS ?件夹添加各?的平台 AMap 调??法。

为 AMap.Android.cs 添加 Android 环境下?德地图的渲染?式

namespace AMap.UI.Apps{ public partial class AMapHandler : ViewHandler<IAMap, MapView> { private AMapHelper _mapHelper; private MapView mapView; internal static Bundle Bundle { get; set; } public AMapHandler(IPropertyMapper mapper, CommandMappercommandMapper = null) : base(mapper, commandMapper) { } protected override MapView CreatePlatformView() { mapView = new Com.Amap.Api.Maps.MapView(Context);03.UIControls.md 7/5/20224 / 8 return mapView; } protected override void ConnectHandler(MapView platformView) { base.ConnectHandler(platformView); AMapLocationClient.UpdatePrivacyAgree(Context, true); AMapLocationClient.UpdatePrivacyShow(Context, true, true); _mapHelper = new AMapHelper(Bundle, platformView); mapView = _mapHelper.CallCreateMap(); } } class AMapHelper : Java.Lang.Object { private Bundle _bundle; private MapView _mapView; public event EventHandler MapIsReady; public MapView Map { get; set; } public AMapHelper(Bundle bundle, MapView mapView) { _bundle = bundle; _mapView = mapView; } public MapView CallCreateMap() {? _mapView.OnCreate(_bundle); return _mapView; } }}

为 AMap.iOS.cs 添加 iOS 环境下?德地图的渲染?式

namespace AMap.UI.Apps{ public partial class AMapHandler : ViewHandler<IAMap, MAMapView> { public AMapHandler(IPropertyMapper mapper, CommandMappercommandMapper = null) : base(mapper, commandMapper) { } protected override MAMapView CreatePlatformView() { MAMapView.UpdatePrivacyShow(AMapPrivacyShowStatus.DidShow,AMapPrivacyInfoStatus.DidContain); MAMapView.UpdatePrivacyAgree(AMapPrivacyAgreeStatus.DidAgree); AMapServices.SharedServices.ApiKey = ""; AMapServices.SharedServices.EnableHTTPS = true; //try //{ MAMapView map = new MAMapView(); map.SetShowsUserLocation(true); map.SetUserTrackingMode(MAUserTrackingMode.Follow); return map; } protected override void ConnectHandler(MAMapView PlatformView) { } protected override void DisconnectHandler(MAMapView PlatformView) { if (PlatformView.Delegate != null) { PlatformView.Delegate.Dispose(); PlatformView.Delegate = null; } PlatformView.RemoveFromSuperview(); } }}

这?我们要修改 MAUI 的项??件,这?有?个设定需要注意的

1. 因为这个控件只是针对 iOS / Android 两个平台,所以我们只保留 net6.0-android 和 net6.0-ios?

2. ?德 SDK 运?建议在真机下使?,特别是 iOS ,需要制定版本号,还有编译环境,我的环境是在 Apple silicon 下所以也要设定好 RuntimeIdentifier,还有就是编译的时候,我花了特别多时间在这?, ?家可以参考我这个在 GitHub 上?问?答的 Issue

  • https://github.com/xamarin/xamarin- macios/issues/15372

 <PropertyGroup Condition="$(TargetFramework.Contains('-ios'))"> <RuntimeIdentifier>ios-arm64</RuntimeIdentifier> <UseMSBuildEngine>true</UseMSBuildEngine> <WarningLevel>4</WarningLevel> <MtouchLink>SdkOnly</MtouchLink> <SupportedOSPlatformVersion>13.0</SupportedOSPlatformVersion> <DeviceSpecificBuild>true</DeviceSpecificBuild> <MtouchDebug>true</MtouchDebug> <MtouchFastDev>true</MtouchFastDev> <MtouchProfiling>true</MtouchProfiling> <MtouchUseSGen>true</MtouchUseSGen> <MtouchUseRefCounting>true</MtouchUseRefCounting> <MtouchFloat32>true</MtouchFloat32> </PropertyGroup>

3.?记得按照平台引?原?库的绑定

 <ItemGroup Condition=" '$(TargetPlatformIdentifier)' == 'ios' "> <ProjectReferenceInclude="..\iOS.AmapSDK.Foundation\iOS.AmapSDK.Foundation.csproj" /> <ProjectReference Include="..\iOS.AmapSDK.3D\iOS.AmapSDK.3D.csproj" />  </ItemGroup>? <ItemGroup Condition=" '$(TargetPlatformIdentifier)' == 'android' "> <ProjectReference Include="..\Droid.AmapSDK\Droid.AmapSDK.csproj" /> </ItemGroup>

最后?步就是在 MauiProgram.cs 上注册?

builder.UseMauiApp<App>().ConfigureFonts(fonts =>{fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");}) .ConfigureMauiHandlers(handlers => { handlers.AddHandler(typeof(AMap), typeof(AMapHandler));});

选择编译运?就可以看到?德地图终于可以在 MAUI 环境下跑起来了

?

小结

对于很多?来说或者都是初步接触了 MAUI ,实际上要做好多平台的兼容还要有?常?的路要?。希望通过这个系列的?章,能给?些第三??商和开发者?些帮助,能尽快提供 MAUI 的?持。这样才能为这个新的技术注?活?。

相关资料:

关注微软中国MSDN了解更多

点击了解MAUI~

?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:34:46  更:2022-07-17 16:38:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/31 5:46:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码