如何构建自动适配谷歌、华为地图的通用封装类 拆分双SDK实现逻辑
跨SDK地图封装的标准实现方案
核心思路是基于接口抽象 + 工厂模式,把适配逻辑从业务代码里剥离,完全不需要在同一个类里同时持有谷歌、华为两套SDK的实例。
第一步:抽离通用的接口契约
把Marker所有的公共能力、用到的坐标类型全部抽象成和具体SDK无关的接口,所有实现类都遵守这个契约:
// 通用坐标抽象,替代原来分别依赖谷歌/华为LatLng的写法 public interface IMapLatLng { double Latitude { get; } double Longitude { get; } } // 通用Marker能力抽象,把所有Marker的公共方法列在这里 public interface IMapMarker { // 统一的位置设置方法 void SetPosition(IMapLatLng latLng); // 其他Marker常用方法按需补充:设置标题、显隐、透明度、点击事件等 void SetTitle(string title); void SetVisible(bool isVisible); }
第二步:编写两套SDK的独立实现类
每个实现类只持有对应SDK的原生Marker对象,没有交叉依赖,也不需要做非空判断:
- 谷歌地图专属实现
public class GoogleMapMarker : IMapMarker { // 仅持有谷歌原生Marker实例 private readonly Android.Gms.Maps.Model.Marker _googleNativeMarker; public GoogleMapMarker(Android.Gms.Maps.Model.Marker googleNativeMarker) { _googleNativeMarker = googleNativeMarker; } public void SetPosition(IMapLatLng latLng) { // 将通用坐标转成谷歌SDK需要的类型 _googleNativeMarker.Position = new Android.Gms.Maps.Model.LatLng( latLng.Latitude, latLng.Longitude ); } public void SetTitle(string title) { _googleNativeMarker.Title = title; } public void SetVisible(bool isVisible) { _googleNativeMarker.Visible = isVisible; } }
- 华为地图专属实现
public class HuaweiMapMarker : IMapMarker { // 仅持有华为原生Marker实例 private readonly Huawei.Hms.Maps.Model.Marker _huaweiNativeMarker; public HuaweiMapMarker(Huawei.Hms.Maps.Model.Marker huaweiNativeMarker) { _huaweiNativeMarker = huaweiNativeMarker; } public void SetPosition(IMapLatLng latLng) { // 将通用坐标转成华为SDK需要的类型 _huaweiNativeMarker.Position = new Huawei.Hms.Maps.Model.LatLng( latLng.Latitude, latLng.Longitude ); } public void SetTitle(string title) { _huaweiNativeMarker.Title = title; } public void SetVisible(bool isVisible) { _huaweiNativeMarker.Visible = isVisible; } }
第三步:实现全局自动适配逻辑
写一个全局的地图服务类,在应用启动时完成一次SDK能力探测,之后所有地图对象的创建都通过这个类统一处理,业务层完全不需要关心当前用的是哪套SDK:
public static class MapService { // 内部标识当前设备可用的地图SDK类型 private enum ActiveMapProvider { Google, Huawei } private static ActiveMapProvider _activeProvider; /// <summary> /// 应用启动时调用一次,完成SDK探测初始化 /// </summary> public static void Init(Context appContext) { // 按需实现探测规则:比如判断设备是否支持GMS服务、是否支持HMS服务 // 常见规则:支持GMS优先用谷歌地图,无GMS的华为设备自动切华为地图 bool isGmsAvailable = /* 检测GMS服务可用性的逻辑 */; _activeProvider = isGmsAvailable ? ActiveMapProvider.Google : ActiveMapProvider.Huawei; } /// <summary> /// 统一的Marker创建入口,对外返回通用的IMapMarker类型 /// </summary> public static IMapMarker CreateMarker(double lat, double lng, string title = "") { // 根据当前激活的SDK,创建对应的Marker实例 if (_activeProvider == ActiveMapProvider.Google) { // 调用谷歌地图原生的AddMarker方法,拿到原生实例后封装成GoogleMapMarker返回 var googleNativeOptions = new Android.Gms.Maps.Model.MarkerOptions() .Position(new Android.Gms.Maps.Model.LatLng(lat, lng)) .SetTitle(title); var nativeMarker = CurrentGoogleMapInstance.AddMarker(googleNativeOptions); return new GoogleMapMarker(nativeMarker); } else { // 华为地图的创建逻辑 var huaweiNativeOptions = new Huawei.Hms.Maps.Model.MarkerOptions() .Position(new Huawei.Hms.Maps.Model.LatLng(lat, lng)) .SetTitle(title); var nativeMarker = CurrentHuaweiMapInstance.AddMarker(huaweiNativeOptions); return new HuaweiMapMarker(nativeMarker); } } }
方案优势
- 完全消除原来的双实例冗余问题,每个实现类仅持有单SDK的原生对象,不存在同时引用两套SDK类型的情况
- 所有SDK适配、非空判断的逻辑全部收敛在框架层,业务层只需要面向
IMapMarker接口编程,不需要写任何if分支判断 - 后续新增第三套地图SDK时,只要新增一个实现
IMapMarker接口的类,在工厂方法里增加对应创建分支即可,原有业务代码零改动
注意:不建议在业务层直接通过
new Marker()的方式创建对象,单靠new操作本身无法完成SDK自动探测和适配逻辑,统一通过MapService的工厂方法创建对象,能从根源上避免适配逻辑散落在各个业务页面中。
内容的提问来源于stack exchange,提问作者Hugo
相关产品推荐
相关产品推荐

