Flutter中release模式下moveNext()函数不执行,debug模式正常
Flutter Release模式下initState中moveNext()函数失效问题
Debug模式下页面加载动画正常,initState内调用的moveNext()可完成页面跳转;切换到Release模式后,moveNext()完全无法执行。已排查AndroidManifest配置,添加了必要权限,相关代码如下:
Dart代码
class _MainAppState extends State<MainApp> { @override void dispose() { super.dispose(); } @override void initState() { moveNext(); _initializeFirebase(); super.initState(); } Future<bool> _onWillPop() async { if (currentPage.length == 1) { return (await showDialog( context: context, builder: (context) => AlertDialog( title: Text('Are you sure?'), content: Text('Do you want to exit'), actions: <Widget>[ TextButton( onPressed: () => Navigator.of(context).pop(false), child: Text('No'), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: Text('Yes'), ), ], ), )) ?? false; } else { Navigation.pop(context); Navigator.pushReplacement(context, MaterialPageRoute(builder: (BuildContext context) => MainApp())); return false; } } void moveNext() async { var prefs = await SharedPreferences.getInstance(); if (!noMove) { bool connected = await InternetConnectionChecker().hasConnection; bool? logIn = true; if (forceLogOut) { logIn = false; } else { if (auth.currentUser != null) { logIn = true; } else { logIn = prefs.getBool("isLoggedIn"); } } if (connected) { Future.delayed(Duration(seconds: 1), () async { setState(() { internetConnected = true; }); if (!forceHomeScreen) { if (logIn != null) { if (logIn) { Future.delayed(Duration(milliseconds: 2000), () async { setState(() { Navigation.pushReplace(context, homePage); setState(() {}); }); }); await AppAPI().getCurrentUser(); await AppAPI().getData(); setState(() {}); } else { Future.delayed(Duration(milliseconds: 2000), () { setState(() { Navigation.pushReplace(context, Welcome()); forceLogOut = false; }); }); } } else { Future.delayed(Duration(milliseconds: 2000), () { setState(() { forceLogOut = false; Navigation.pushReplace(context, Welcome()); setState(() {}); }); }); } } else { setState(() { Navigation.pushReplace(context, homePage); setState(() {}); }); } }); } else { Future.delayed(Duration(seconds: 2), () { setState(() { internetConnected = false; Navigation.pushReplace(context, NoInternet()); setState(() {}); }); }); } } else { Future.delayed(Duration(seconds: 2)); setState(() {}); } } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: _onWillPop, child: MaterialApp( debugShowCheckedModeBanner: false, home: currentPage.last)); } }
AndroidManifest.xml代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <application android:label="ThePhotographers" android:name="${applicationName}" android:icon="@mipmap/launcher_icon"> <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"> <!-- Specifies an Android theme to apply to this Activity as soon as the Android process has started. This theme is visible to the user while the Flutter UI initializes. After that, this theme continues to determine the Window background behind the Flutter UI. --> <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> <!-- Don't delete the meta-data below. This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> <meta-data android:name="flutterEmbedding" android:value="2" /> </application> </manifest>
解决方法
1. 捕获异步异常
Release模式下异步错误会静默失败,给moveNext()添加try-catch捕获异常,便于排查问题:
void moveNext() async { try { var prefs = await SharedPreferences.getInstance(); // 原函数逻辑 } catch (e, stackTrace) { print('moveNext执行异常: $e\n$stackTrace'); // 可选:添加错误 fallback 逻辑,比如跳转到欢迎页 } }
2. 调整Firebase初始化顺序
当前initState先执行moveNext()再初始化Firebase,Release模式下auth.currentUser可能未就绪,导致逻辑错误。修改顺序确保Firebase初始化完成后再执行moveNext():
@override void initState() { super.initState(); _initializeFirebase().then((_) { moveNext(); }); }
3. 处理SharedPreferences空值
prefs.getBool("isLoggedIn")可能返回null,给logIn设置默认值避免分支逻辑异常:
logIn = prefs.getBool("isLoggedIn") ?? false;
4. 简化异步流程
嵌套的Future.delayed和setState可能导致Release模式下UI线程阻塞,改用顺序await简化逻辑:
if (connected) { await Future.delayed(Duration(seconds: 1)); setState(() => internetConnected = true); if (!forceHomeScreen) { await Future.delayed(Duration(milliseconds: 2000)); final shouldLogin = logIn ?? false; if (shouldLogin) { await AppAPI().getCurrentUser(); await AppAPI().getData(); Navigation.pushReplace(context, homePage); } else { Navigation.pushReplace(context, Welcome()); setState(() => forceLogOut = false); } } else { Navigation.pushReplace(context, homePage); } } else { await Future.delayed(Duration(seconds: 2)); setState(() => internetConnected = false); Navigation.pushReplace(context, NoInternet()); }
5. 添加混淆规则
Release模式代码混淆可能导致第三方库(如SharedPreferences、Firebase)失效,在android/app/proguard-rules.pro中添加规则:
# 保留SharedPreferences相关类 -keep class android.content.SharedPreferences { *; } -keep class android.content.SharedPreferences$Editor { *; } # 保留Firebase Auth类 -keep class com.google.firebase.auth.** { *; } # 保留网络检测相关类 -keep class java.net.InetAddress { *; }
内容的提问来源于stack exchange,提问作者CodeVault
相关产品推荐
相关产品推荐

