Flutter Release模式启动失败:无法实例化FlutterFragment子类
Release模式启动失败,Debug/其他模式正常
错误信息
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.App8.Whistle/com.App8.Whistle.MainActivity}: java.lang.RuntimeException: Could not instantiate FlutterFragment subclass (io.flutter.embedding.android.b)
相关代码文件
MainActivity.kt
package com.App8.Whistle import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.plugin.common.MethodChannel import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity: FlutterFragmentActivity() { override fun configureFlutterEngine(flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine); MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "flavor").setMethodCallHandler { _, result -> result.success(BuildConfig.FLAVOR) } } }
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/> <application android:label="@string/app_name" android:name="${applicationName}" android:usesCleartextTraffic="true" android:icon="@mipmap/ic_launcher"> <activity android:name="MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <meta-data android:name="flutterEmbedding" android:value="2" /> </application> </manifest>
android/app/build.gradle
def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new FileNotFoundException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.App8.Whistle" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion 23 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } flavorDimensions "flavor" productFlavors{ dev{ dimension "flavor" resValue "string","app_name","App8 Whist Dev" applicationIdSuffix ".dev" versionNameSuffix " Dev" } qa{ dimension "flavor" resValue "string","app_name","App8 Whist QA" applicationIdSuffix ".qa" versionNameSuffix " Qa" } prod{ dimension "flavor" resValue "string","app_name","App8 Whist" } } namespace 'com.App8.Whistle' } flutter { source '../..' } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" }
问题原因
这个错误是Release模式下代码混淆导致的:Flutter内部的FlutterFragment子类被混淆工具重命名为io.flutter.embedding.android.b,系统无法通过反射正确实例化该类。Debug模式默认关闭混淆,所以运行正常。
解决方案
1. 添加Flutter混淆规则
在android/app/proguard-rules.pro文件中添加以下规则,保护Flutter核心类不被混淆:
# Flutter核心类混淆保护 -keep class io.flutter.app.** { *; } -keep class io.flutter.plugin.** { *; } -keep class io.flutter.util.** { *; } -keep class io.flutter.view.** { *; } -keep class io.flutter.** { *; } -keep class io.flutter.plugins.** { *; } -dontwarn io.flutter.embedding.**
2. 确认Release构建配置
检查build.gradle中Release构建类型的配置,确保混淆开启并应用了上述规则:
buildTypes { release { signingConfig signingConfigs.debug minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } }
3. 清理缓存并重新构建
执行以下命令清理项目缓存,然后重新构建Release版本:
flutter clean flutter build apk --release
如果问题仍未解决,尝试更新Flutter SDK到最新稳定版本,确保依赖兼容性。
内容的提问来源于stack exchange,提问作者Joel
相关产品推荐
相关产品推荐

