.NET8 Android绑定双库时出现ClassNotFoundException问题求助
核心问题
将Xamarin应用迁移至.NET8后,同时引用两个Android绑定库A(含少量原生代码)和B时,调用A的类(如keepass2android.kbbridge.KeyboardData)会抛出Java.Lang.ClassNotFoundException;单独引用A时功能正常,原Xamarin环境下两个库可正常共存。
排查思路
检查混淆/压缩规则冲突:
确认两个绑定库的R8/ProGuard规则是否误移除了对方的类。.NET8 Android默认启用R8,若其中一个库的配置中存在不当的通配符规则,可能导致A的类被剥离。查看绑定项目的ProGuard.cfg和Metadata.xml,重点排查<remove-node>、<attr>或-keep规则是否存在冲突。验证绑定生成的C#代码:
检查绑定项目生成的C#类,确认KeyboardData的[Register]属性是否正确指向Java类keepass2android.kbbridge.KeyboardData;同时确认A和B的命名空间是否存在重叠,导致类生成冲突。检查原生库兼容性:
库A包含原生SO文件,确认其架构(如arm64-v8a)与库B的SO架构一致。查看APK解压后的lib目录,确认A的SO文件是否存在,避免因架构不匹配导致原生依赖加载失败,间接引发类加载异常。对比.NET8与Xamarin绑定差异:
.NET8对Android绑定的处理逻辑有变更,比如Dex合并策略、Desugar默认启用状态。尝试临时禁用Desugar或切换Dex工具(从d8改为dx),验证是否是新特性导致的问题。检查Dex文件内容:
使用dexdump工具分析最终APK中的Dex文件,确认keepass2android.kbbridge.KeyboardData类是否存在。若不存在,说明类被压缩工具移除;若存在,则需排查类加载路径问题。
可行解决方案
添加明确的类保留规则:
在两个绑定项目的ProGuard.cfg中添加:-keep class keepass2android.kbbridge.** { *; } -keep class keepass2android.plugin.** { *; }强制R8保留两个库的所有类,避免误剥离。
修正绑定配置:
检查绑定项目的Metadata.xml,移除可能导致类被排除的配置;若自动绑定遗漏了类,可添加<add-node>手动指定要保留的类。统一架构配置:
在主项目和所有绑定项目的.csproj中添加:<AndroidSupportedAbis>arm64-v8a;armeabi-v7a</AndroidSupportedAbis>确保所有库的原生SO文件架构一致,避免加载冲突。
禁用Desugar:
在主项目的.csproj中添加:<AndroidEnableDesugar>false</AndroidEnableDesugar>关闭Desugar特性,验证是否是其对旧代码的处理导致类加载失败。
手动调整绑定代码:
若自动生成的C#类存在错误,手动修改绑定项目中KeyboardData类的[Register]属性,确保Java类名完全匹配,例如:[Register("keepass2android/kbbridge/KeyboardData", DoNotGenerateAcw = true)] public partial class KeyboardData : Java.Lang.Object { // ... 类内容 }
内容的提问来源于stack exchange,提问作者Philipp

