Xamarin集成HMS时AGConnectServicesConfig仅首次读取agconnect-services.json异常
Xamarin.Forms集成HMS套件配置仅首次读取生效问题修复
问题表现
- 集成华为HMS地图、分析、崩溃、推送服务到Xamarin.Forms应用时,
agconnect-services.json配置文件仅在应用首次安装后第一次启动时可被正常读取 - 首次启动后,执行代码
var appId = AGConnectServicesConfig.FromContext(this).GetString("client/app_id");返回值恒为null - Release模式下问题稳定复现,仅卸载应用重装后可临时恢复配置读取能力
- 已尝试降级HMS相关NuGet包、替换第三方开源绑定库、自行编写绑定库,问题均未解决
问题根因
- 自定义
ContentProvider初始化优先级设置错误:InitOrder数值越大初始化执行时机越晚,当前设置的99远晚于HMS SDK内置初始化Provider的执行时机,配置注入操作发生在SDK首次读取配置之后,无法覆盖SDK已加载的空配置 - HMS SDK会将首次读取到的配置持久化到应用私有缓存目录,后续启动优先读取本地缓存,不会主动触发自定义实现的
HmsLazyInputStream读取逻辑 - 自定义
ContentProvider的authorities硬编码为测试包名,若与应用实际包名不匹配,部分ROM上该Provider仅会在应用首次安装时触发一次OnCreate,后续冷启动不会执行配置注入逻辑
修复方案
1. 修正ContentProvider配置
将初始化优先级调整为最高优先级,authorities替换为应用实际包名,避免Provider不执行或执行过晚:
// InitOrder设为0保证优先执行,authorities替换为你应用的实际包名 [ContentProvider(new string[] { "替换为你的应用实际包名.XamarinCustomProvider" }, InitOrder = 0)] public class XamarinCustomProvider : ContentProvider { public override int Delete(Android.Net.Uri uri, string selection, string[] selectionArgs) { throw new NotImplementedException(); } public override string GetType(Android.Net.Uri uri) { throw new NotImplementedException(); } public override Android.Net.Uri Insert(Android.Net.Uri uri, ContentValues values) { throw new NotImplementedException(); } public override bool OnCreate() { AGConnectServicesConfig config = AGConnectServicesConfig.FromContext(Context); // 清除SDK本地缓存的历史配置,强制重新加载 config.ClearAll(); config.OverlayWith(new HmsLazyInputStream(Context)); return false; } public override ICursor Query(Android.Net.Uri uri, string[] projection, string selection, string[] selectionArgs, string sortOrder) { throw new NotImplementedException(); } public override int Update(Android.Net.Uri uri, ContentValues values, string selection, string[] selectionArgs) { throw new NotImplementedException(); } }
2. 保持HmsLazyInputStream实现不变
原有流读取逻辑无问题,无需修改:
public class HmsLazyInputStream : LazyInputStream { public HmsLazyInputStream(Context context) : base(context) { } public override Stream Get(Context context) { try { return context.Assets.Open("agconnect-services.json"); } catch (Exception e) { Log.Error("Hms", $"Failed to get input stream" + e.Message); return null; } } }
3. 调整MainActivity初始化时机
确保所有HMS服务初始化、配置读取逻辑都在base.OnCreate(savedInstanceState)执行完成后调用,避免Context未完全初始化导致的读取失败:
protected override void OnCreate(Bundle savedInstanceState) { // 必须先执行基类OnCreate base.OnCreate(savedInstanceState); if (useHMSService) { AGConnectCrash.Instance.SetUserId("Anonymous user"); HiAnalyticsTools.EnableLog(); var instance = HiAnalytics.GetInstance(this); instance.SetAnalyticsEnabled(true); instance.SetReportPolicies(new List<ReportPolicy> { ReportPolicy.OnAppLaunchPolicy }); MapsInitializer.SetApiKey("你的实际APIKEY"); HmsMessaging.GetInstance(this).AutoInitEnabled = true; var appId = AGConnectServicesConfig.FromContext(this).GetString("client/app_id"); if (!string.IsNullOrWhiteSpace(appId)) { AlertDialog.Builder alert = new AlertDialog.Builder(this); alert.SetTitle("AppID"); alert.SetMessage(appId); Dialog dialog = alert.Create(); dialog.Show(); } } }
验证说明
修改完成后无需卸载应用,覆盖安装后二次启动即可正常读取到app_id,Release模式下也不会复现配置丢失问题。
内容的提问来源于stack exchange,提问作者Nestor Daniel Flores
相关产品推荐
相关产品推荐

