You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止R8移除Flutter插件第三方库代码并解决编译错误

Flutter插件Release模式下R8编译报错(缺失BouncyCastle/Conscrypt/OpenJSSE类)

背景

我开发了一个Flutter插件,其Android模块引入以下依赖:

implementation 'com.microsoft.signalr:signalr:8.0.4'
implementation 'org.slf4j:slf4j-api:2.0.13'
implementation 'org.slf4j:slf4j-jdk14:2.0.13'

testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.2.0'

插件托管在GitHub,通过Flutter应用的pubspec.yaml引入依赖。

调试模式下功能正常,但切换到release模式时编译失败,R8报大量类缺失错误:

ERROR: Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in /Users/haidarmehsen/Work/acksession/flutter/vsa-tablet/build/app/outputs/mapping/release/missing_rules.txt.
ERROR: R8: Missing class org.bouncycastle.jsse.BCSSLParameters (referenced from: void okhttp3.internal.platform.BouncyCastlePlatform.configureTlsExtensions(javax.net.ssl.SSLSocket, java.lang.String, java.util.List) and 1 other context)
Missing class org.bouncycastle.jsse.BCSSLSocket (referenced from: void okhttp3.internal.platform.BouncyCastlePlatform.configureTlsExtensions(javax.net.ssl.SSLSocket, java.lang.String, java.util.List) and 5 other contexts)
Missing class org.bouncycastle.jsse.provider.BouncyCastleJsseProvider (referenced from: void okhttp3.internal.platform.BouncyCastlePlatform.<init>())
Missing class org.conscrypt.Conscrypt$Version (referenced from: boolean okhttp3.internal.platform.ConscryptPlatform$Companion.atLeastVersion(int, int, int))
Missing class org.conscrypt.Conscrypt (referenced from: boolean okhttp3.internal.platform.ConscryptPlatform$Companion.atLeastVersion(int, int, int) and 4 other contexts)
Missing class org.conscrypt.ConscryptHostnameVerifier (referenced from: okhttp3.internal.platform.ConscryptPlatform$DisabledHostnameVerifier)
Missing class org.openjsse.javax.net.ssl.SSLParameters (referenced from: void okhttp3.internal.platform.OpenJSSEPlatform.configureTlsExtensions(javax.net.ssl.SSLSocket, java.lang.String, java.util.List))
Missing class org.openjsse.javax.net.ssl.SSLSocket (referenced from: void okhttp3.internal.platform.OpenJSSEPlatform.configureTlsExtensions(javax.net.ssl.SSLSocket, java.lang.String, java.util.List) and 1 other context)
Missing class org.openjsse.net.ssl.OpenJSSE (referenced from: void okhttp3.internal.platform.OpenJSSEPlatform.<init>())
FAILURE: Build failed with an exception.

自动生成的missing_rules.txt内容:

# Please add these rules to your existing keep rules in order to suppress warnings.
# This is generated automatically by the Android Gradle plugin.
-dontwarn org.bouncycastle.jsse.BCSSLParameters
-dontwarn org.bouncycastle.jsse.BCSSLSocket
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
-dontwarn org.conscrypt.Conscrypt$Version
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.ConscryptHostnameVerifier
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE

已尝试的方案

  • 添加上述-dontwarn规则:编译通过,但插件运行时报错
  • 添加-keep规则保留缺失类:编译错误依旧
    -keep class org.bouncycastle.jsse.BCSSLParameters { *; }
    -keep class org.bouncycastle.jsse.BCSSLSocket { *; }
    -keep class org.bouncycastle.jsse.provider.BouncyCastleJsseProvider { *; }
    -keep class org.conscrypt.Conscrypt$Version { *; }
    -keep class org.conscrypt.Conscrypt { *; }
    -keep class org.conscrypt.ConscryptHostnameVerifier { *; }
    -keep class org.openjsse.javax.net.ssl.SSLParameters { *; }
    -keep class org.openjsse.javax.net.ssl.SSLSocket { *; }
    -keep class org.openjsse.net.ssl.OpenJSSE { *; }
    
  • 完全禁用R8(release配置中minifyEnabled=false、shrinkResources=false):有效但应用体积翻倍,不接受

问题

如何在不关闭代码压缩的前提下解决该编译错误?


解决方案

这些缺失类是OkHttp为兼容不同TLS实现(BouncyCastle/Conscrypt/OpenJSSE)引入的可选依赖,你的项目里并没有实际引入这些库,所以R8在压缩时会报错。正确的处理方式是结合-dontwarn和针对OkHttp平台类的-keep规则,而不是保留那些不存在的类。

  1. 在Flutter插件的Android模块中创建/修改proguard-rules.pro文件,添加以下规则:
# 允许忽略缺失的可选TLS实现类
-dontwarn org.bouncycastle.jsse.**
-dontwarn org.conscrypt.**
-dontwarn org.openjsse.**

# 保留OkHttp的平台检测类,避免R8误删导致运行时找不到实现
-keep class okhttp3.internal.platform.** { *; }
-keep interface okhttp3.internal.platform.Platform { *; }
  1. 确保插件的build.gradle中正确配置ProGuard规则(如果还没配置):
android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
  1. 如果你是在Flutter应用端配置,也可以在应用的Android模块proguard-rules.pro中添加上述规则,但更推荐在插件内部配置,这样所有使用该插件的应用都无需额外处理。

原理

OkHttp会在运行时检测当前环境可用的TLS实现,这些BouncyCastle/Conscrypt/OpenJSSE类是可选依赖,并非必须存在。之前单独加-dontwarn导致运行时报错,是因为R8把OkHttp的平台检测相关类也给压缩删除了,所以需要保留OkHttp的平台类,确保运行时能正常走默认的TLS实现逻辑。

内容的提问来源于stack exchange,提问作者Haidar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 00:27:34