Flutter Flavors启动报错:无法实例化MainActivity类
问题现象
执行flutter run --flavor app1 -t lib/app1/main_app1.dart启动app1 flavor时,抛出RuntimeException,系统试图查找com.example.app2.MainActivity类,触发ClassNotFoundException。新增app3 flavor后,无论启动哪个flavor,系统都会查找build.gradle中最后定义的flavor对应的MainActivity;调整flavors顺序后问题依旧。
错误日志
E/AndroidRuntime(17964): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.app1/com.example.app2.MainActivity}:
java.lang.ClassNotFoundException: Didn't find class "com.example.app2.MainActivity"
~on path: DexPathList[[zip file "/data/app/~~xTXnETzgZ59Wy84-KLdYow==/com.example.app1-OrwtX9mCvNmedVCBgPKdOw==/base.apk"],nativeLibraryDirectories=[/data/app/~~xTXnETzgZ59Wy84-KLdYow==/com.example.app1-OrwtX9mCvNmedVCBgPKdOw==/lib/arm64, /data/app/~~xTXnETzgZ59Wy84-KLdYow==/com.example.app1-OrwtX9mCvNmedVCBgPKdOw==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]]
E/AndroidRuntime(17964): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3898)
E/AndroidRuntime(17964): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4144)
E/AndroidRuntime(17964): at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
E/AndroidRuntime(17964): at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
E/AndroidRuntime(17964): at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:99)
E/AndroidRuntime(17964): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2589)
E/AndroidRuntime(17964): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime(17964): at android.os.Looper.loopOnce(Looper.java:224)
E/AndroidRuntime(17964): at android.os.Looper.loop(Looper.java:318)
E/AndroidRuntime(17964): at android.app.ActivityThread.main(ActivityThread.java:8765)
E/AndroidRuntime(17964): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(17964): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:561)
E/AndroidRuntime(17964): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
相关配置
android/app/build.gradle
android { ... flavorDimensions "default" productFlavors { app1 { dimension "default" namespace "com.example.app1" applicationId "com.example.app1" resValue "string", "app_name", "App 1" signingConfig signingConfigs.app1 } zpp2 { dimension "default" namespace "com.example.app2" applicationId "com.example.app2" resValue "string", "app_name", "App 2" signingConfig signingConfigs.app2 } } ... }
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application android:label="flavor_example_config" android:name="${applicationName}" 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> <queries> <intent> <action android:name="android.intent.action.PROCESS_TEXT"/> <data android:mimeType="text/plain"/> </intent> </queries> </manifest>
解决方案
原因分析
每个flavor配置了独立的namespace,但MainActivity仅存在于通用的src/main目录下,导致编译时gradle错误地使用最后一个flavor的namespace生成Activity全类名,而当前flavor的APK中并不存在该类。
修复步骤
为每个flavor创建独立的MainActivity
在android/app/src目录下,为每个flavor创建对应文件夹(如app1、zpp2、app3),并在文件夹内建立与flavornamespace匹配的包结构,放入对应的MainActivity:- app1路径:
src/app1/kotlin/com/example/app1/MainActivity.kt - zpp2路径:
src/zpp2/kotlin/com/example/app2/MainActivity.kt
每个MainActivity代码可复用,只需保证包名与对应flavor的namespace一致。
- app1路径:
保持MainManifest配置不变
src/main/AndroidManifest.xml中的android:name=".MainActivity"无需修改,gradle会自动根据当前flavor合并对应目录下的Activity类,确保全类名匹配。清理编译缓存
执行以下命令清除残留缓存,避免旧编译文件干扰:
flutter clean cd android && ./gradlew clean cd .. && flutter pub get
- 验证启动命令
启动对应flavor时,确保指定正确的Dart入口文件:
flutter run --flavor app1 -t lib/app1/main_app1.dart flutter run --flavor zpp2 -t lib/app2/main_app2.dart
注意:build.gradle中第二个flavor命名为
zpp2但applicationId是com.example.app2,建议统一命名避免混淆。
内容的提问来源于stack exchange,提问作者rphl

