从MvvmCross 5.6.2升级到6.4.2时如何加载插件
解决MvvmCross 6.4.2 Android插件加载空引用异常问题
问题分析
从MvvmCross 5.6.2升级到6.4.2后,编译通过但运行时触发空引用异常,核心原因是重写的GetPluginAssemblies方法未返回任何程序集,导致LoadPlugins遍历空集合时出错。本质是Android平台下AppDomain.CurrentDomain.GetAssemblies()无法自动加载所有引用的插件程序集,或默认的引用判断逻辑失效。
可行解决方案
1. 替换GetPluginAssemblies实现,手动指定插件程序集
放弃自动扫描逻辑,直接返回项目中实际使用的插件程序集,避免依赖AppDomain的自动扫描:
public override IEnumerable<Assembly> GetPluginAssemblies() { // 替换为你项目中用到的插件程序集 return new List<Assembly> { typeof(MvxLocationPlugin).Assembly, typeof(MvxMessengerPlugin).Assembly // 依次添加所有插件程序集 }; }
2. 恢复Bootstrap文件(兼容旧插件)
虽然MvvmCross 6.x支持自动加载插件,但部分旧插件可能未适配自动扫描逻辑,恢复原有的Bootstrap文件即可快速解决:
- 为每个插件创建对应的Bootstrap类,例如
LocationPluginBootstrap.cs:
public class LocationPluginBootstrap : MvxPluginBootstrapAction<MvvmCross.Plugins.Location.PluginLoader> { }
- 确保Bootstrap类所在的命名空间能被MvvmCross扫描到(默认会扫描项目所有程序集)。
3. 手动注册插件(最直接的过渡方案)
在Setup的InitializeLastChance方法中手动注册所有插件,跳过自动扫描流程:
protected override void InitializeLastChance() { base.InitializeLastChance(); var pluginManager = Mvx.Resolve<IMvxPluginManager>(); // 逐个加载用到的插件 pluginManager.EnsurePluginLoaded<MvvmCross.Plugins.Location.Plugin>(); pluginManager.EnsurePluginLoaded<MvvmCross.Plugins.Messenger.Plugin>(); }
4. 修复自动扫描逻辑
如果坚持使用自动扫描,调整GetPluginAssemblies中的判断逻辑,手动触发未加载的插件程序集:
public override IEnumerable<Assembly> GetPluginAssemblies() { var mvxAssemblyName = typeof(MvxPluginAttribute).Assembly.GetName().Name; var allAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); // 手动加载未被AppDomain自动加载的插件程序集 var pluginAssemblyNames = new List<string> { "MvvmCross.Plugins.Location", "MvvmCross.Plugins.Messenger" }; foreach (var name in pluginAssemblyNames) { if (!allAssemblies.Any(a => a.GetName().Name == name)) { var assembly = Assembly.Load(new AssemblyName(name)); allAssemblies.Add(assembly); } } return allAssemblies.Where(asmb => { try { return asmb.GetReferencedAssemblies().Any(ra => ra.Name == mvxAssemblyName); } catch { return false; } }); }
关键注意事项
- MvvmCross 6.x的自动加载依赖
MvxPluginAttribute标记,确保使用的插件版本已添加该属性; - Android平台下程序集不会即时加载,手动触发加载能避免扫描不到的问题;
- 过渡阶段优先尝试手动注册或恢复Bootstrap,这两种方式稳定性最高。
内容的提问来源于stack exchange,提问作者UnreachableCode
相关产品推荐
相关产品推荐

