升级Android支持库至27.0.2后Xamarin应用仅发布模式崩溃
这种只在发布模式触发的启动崩溃,我之前也碰到过类似情况,根源几乎都是ProGuard混淆破坏了Dagger的依赖注入逻辑——尤其是你升级支持库和目标API后,ProGuard的默认规则和第三方库(这里是Vungle)的注入代码发生了冲突。
问题分析
日志里的java.lang.IllegalStateException: Errors creating object graph: java.lang.String has no injectable members清晰说明:Dagger初始化依赖图时,被混淆后的代码错误地要求注入java.lang.String。但String本身并没有@Inject标注的构造函数,自然会抛出异常。而错误关联到Vungle的ProtocolHttpRequest类,说明Vungle内部用到了Dagger,却被ProGuard把注入相关代码搞乱了。
解决方案
你需要在ProGuard规则文件(通常是proguard-rules.pro)中添加以下规则,保护Dagger和Vungle的注入逻辑不被混淆:
1. 保留Dagger核心类与注入点
# Dagger 2 核心保护规则 -keep class dagger.** { *; } -keep interface dagger.** { *; } -keep class * extends dagger.internal.Binding -keep class * extends dagger.internal.ModuleAdapter -keep class * extends dagger.internal.StaticInjection # 保留所有带@Inject注解的构造方法 -keepclassmembers,allowobfuscation class * { @javax.inject.Inject <init>(...); } # 保留所有@Provides注解的方法 -keepclassmembers class * { @dagger.Provides *; } # 保留Dagger自动生成的辅助类 -keep class **_MembersInjector { *; } -keep class **_Factory { *; } -keep class **_Module { *; }
2. 保留Vungle SDK的注入相关代码
因为错误来自Vungle的内部类,必须确保它的注入逻辑不被混淆:
# Vungle SDK 专属混淆规则 -keep class com.vungle.publisher.** { *; } -keepclassmembers class com.vungle.publisher.** { @javax.inject.Inject <init>(...); @dagger.Provides *; }
3. 检查R8兼容性(AGP 3.0+ 用户)
如果你用的是Android Gradle Plugin 3.0及以上版本,默认会启用R8代替ProGuard。如果添加上述规则后仍有问题,可以暂时在gradle.properties中禁用R8测试:
android.enableR8=false
验证步骤
修改完规则后,重新构建发布版本(执行./gradlew assembleRelease),安装到设备上测试启动情况,应该就能解决崩溃问题了。
内容的提问来源于stack exchange,提问作者Joyce de Lanna

