dart Flutter :热重新加载后,应用程序继续返回初始路径

11dmarpk  于 5个月前  发布在  Flutter
关注(0)|答案(3)|浏览(92)

我刚刚根据迁移指南https://firebase.flutter.dev/docs/migration将FireBase插件升级到最新版本,并开始注意到每当我进行热重新加载时,我的应用程序都会进行热重启并返回初始路由。首先,我认为这可能是Android Studio问题,所以我也尝试了命令提示符和VS代码,但同样的结果.我已经搜索了旧的Stackoverflow问题相关的主题,但找不到任何可以解决这个问题.我复制我的代码下面. PS:我对Flutter很陌生,这是我在stackoverflow中的第一个问题。
非常感谢任何帮助。编辑:刚刚调试了一下,发现执行热重新加载时会返回runApp(...)。
main.dart

void main() async {
  String authMethod;
  WidgetsFlutterBinding.ensureInitialized();
  SharedPreferenceService localStorage = SharedPreferenceService();
  authMethod = await localStorage.getAuthMode();
  print("Authentication Mode $authMethod");
  setupLocator();

  runApp(
    DevicePreview(
        enabled: false,//kReleaseMode,
        builder: (context)=>AppInitialization())
      );
}

字符集
AppInitialization.dart

class AppInitialization extends StatelessWidget {
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _initialization,
        builder: (context, snapshot) {
        if (snapshot.hasError) {
          return Center(
            child: Container(
              child: Text('Unable to Initialize FireBase'),
            ),
          );
        }
        if (snapshot.connectionState == ConnectionState.done) {
          print("======= F I R E  B A S E  A P P ========");
          return LocalGroceryOnline();
        }
        return Center(
          child: SizedBox(
            height: 40,
            width: 40,
            child: CircularProgressIndicator(
                strokeWidth: 2.0,
                valueColor: AlwaysStoppedAnimation<Color>(Colors.redAccent, )),
          ),
        );

        });
  }
}


LocalGroceryOnline.dart

class LocalGroceryOnline extends StatelessWidget {
  final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
  @override
  Widget build(BuildContext context) {    
    return MultiProvider  (
      providers: [
        Provider<FirebaseAuthService>(create: (_) => FirebaseAuthService()),
        Provider<SignInHelperService>(create: (_) => SignInHelperService()),
        Provider<SharedPreferenceService>(create: (_) => SharedPreferenceService()),
        ChangeNotifierProvider<CartModel>(create: (_) => CartModel()),
        ChangeNotifierProvider<UserModel>(create: (_) => UserModel()),
        ChangeNotifierProvider<ProductModel>(create: (_) => ProductModel()),
        ChangeNotifierProvider<cat.Category>(create: (_) => cat.Category()),
        ChangeNotifierProvider<AppSetting>(create: (_) => AppSetting()),
        ChangeNotifierProvider<ValueNotifier<bool>>(create: (_) => ValueNotifier<bool>(false),),
        ChangeNotifierProvider<ValueNotifier<int>>(create: (_) => ValueNotifier<int>(0),)

      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Online Local Grocery',
        locale: DevicePreview.of(context).locale,
        builder: DevicePreview.appBuilder,
        theme: ThemeData(
          primaryColor: Colors.white,
          fontFamily: 'Montserrat',
          appBarTheme: AppBarTheme(elevation: 0.0), //This is important

        ),
        initialRoute: AuthWidget.id,
        navigatorKey: navigatorKey,

        onGenerateRoute: RouteGenerator.generateRoute,
        //onGenerateInitialRoutes: InitialRouteGenerator.generateRoute(),
      )
          ,
    );
  }
}


RouteGenerator.dart

class RouteGenerator {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    final args = settings.arguments;

    switch (settings.name) {
      case AuthWidget.id:
        return MaterialPageRoute(builder: (_) => AuthWidget());

      case SignUpSelectionScreen.id:
        return MaterialPageRoute(builder: (_) => SignUpSelectionScreen());
      case SignupForm.id:
        return MaterialPageRoute(builder: (_) => SignupForm());
      case LoginView.id:
        return MaterialPageRoute(builder: (_) => LoginView());
      case HomePage.id:
        return MaterialPageRoute(builder: (_) => HomePage());
      case MainPage.id:
        if (args.runtimeType == MainCategory) {
          return MaterialPageRoute(
              builder: (_) => MainPage(
                mainCategory: args,
              ));
        }
        return _errorRoute();
      case ProductDetail.id:
        if (args.runtimeType == SelectedProductArguments) {
          return MaterialPageRoute(
              builder: (_) => ProductDetail(
                    selectedProductArguments: args,
                  ));
        }
        return _errorRoute();
      case CheckOutScreen.id:
        return MaterialPageRoute(builder: (_) => CheckOutScreen());
      case Admin.id:
        return MaterialPageRoute(builder: (_) => Admin());
      case ScrapBoard.id:
        return MaterialPageRoute(builder: (_) => ScrapBoard());
      case ProductAdminView.id:
        return MaterialPageRoute(builder: (_) => ProductAdminView());
      case DeliveryAddressView.id:
        return MaterialPageRoute(builder: (_) => DeliveryAddressView());
      case PaymentView.id:
        return MaterialPageRoute(builder: (_) => PaymentView());
      case OrderProcessingView.id:
        return MaterialPageRoute(builder: (_) => OrderProcessingView());
      case MyOrdersView.id:
        return MaterialPageRoute(builder: (_) => MyOrdersView());
      case MyOrderDetails.id:
        if (args.runtimeType == Order) {
        return MaterialPageRoute(builder: (_) => MyOrderDetails(
          order: args,
        )
         );
        }
        return _errorRoute();

      default:
        // If there is no such named route in the switch statement, e.g. /third
        return _errorRoute();
    }
  }

  static Route<dynamic> _errorRoute() {
    return MaterialPageRoute(builder: (_) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Error'),
        ),
        body: Center(
          child: Text('ERROR'),
        ),
      );
    });
  }
}

class InitialRouteGenerator {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    bool _firstTimeAppUsed;
    final localStorage = new SharedPreferenceService();
    localStorage.isFirstTimeAppUsed().then((bool value) {
      if (value == true) {
        _firstTimeAppUsed = true;
      }
    });
    if (_firstTimeAppUsed) {
      return MaterialPageRoute(builder: (_) => SignUpSelectionScreen());
    }
    return MaterialPageRoute(builder: (_) => HomePage());
  }
}


AuthWidget.dart

class AuthWidget extends StatelessWidget {
  static const id = "auth_widget";

  @override
  Widget build(BuildContext context) {
    print("Auth Widget...");
    final authService =
        Provider.of<FirebaseAuthService>(context, listen: false);
    final userModel = Provider.of<UserModel>(context, listen: false);
    final signInHelperService = Provider.of<SignInHelperService>(context, listen: false);

    return StreamBuilder(
        stream: authService.onAuthStateChanged,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.active) {
            print ("INSIDE AUTH WIDGET");
            final user = snapshot.data;
            if (user != null) {
              print("${user.uid} ${user.userName} ${user.photoUrl}");
              userModel.user = user;
              return StreamBuilder(
                  stream: FirebaseFirestore.instance
                      .collection('users')
                      .doc(user.uid)
                      .get().asStream(),
                  builder: (context, userSnapshot) {
                    if (userSnapshot.hasData && snapshot.connectionState == ConnectionState.active) {
                      final userDocument = userSnapshot.data;
                      if (userDocument != null) {
                        print("------ Data Found -------");
                        AppUser user = AppUser.fromMap(userDocument);
                        //bool signUpComplete = userDocument["signUpComplete"];
                        bool signUpComplete = user.signUpComplete;
                        if (signUpComplete == null) signUpComplete = false;
                        if (!signUpComplete) {
                          print("userModel.user UID ${userModel.user.uid}");
                          return SignupForm();
                        } else {
                          AppUser user2 = AppUser.fromMap(userDocument);
                          userModel.user = user2;
                          print('User Level ..... ${userModel.user.userLevel}');
                          signInHelperService.getAndUpdateDeviceToken(user2);

                          return HomePage(); //MainPage();
                        }
                      }
                    }
                    return emptyScaffoldWithProgress();
                  });
            }
            return SignUpSelectionScreen();
          }
          return emptyScaffoldWithProgress();
        });
  }

  Scaffold emptyScaffoldWithProgress() {
    return Scaffold(
      body: Center(
        child: SizedBox(
          height: 90,
          width: 90,
          child: CircularProgressIndicator(
              strokeWidth: 5.0,
              valueColor: AlwaysStoppedAnimation<Color>(Colors.redAccent)),
        ),
      ),
    );
  }
}


扑动医生-v

[√] Flutter (Channel stable, 1.22.4, on Microsoft Windows [Version 10.0.19041.630], locale en-US)
    • Flutter version 1.22.4 at C:\src\flutter
    • Framework revision 1aafb3a8b9 (3 weeks ago), 2020-11-13 09:59:28 -0800
    • Engine revision 2c956a31c0
    • Dart version 2.10.4

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at C:\Users\Jamal\AppData\Local\Android\sdk
    • Platform android-29, build-tools 29.0.3
    • Java binary at: C:\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    • All Android licenses accepted.

[√] Android Studio (version 4.0)
    • Android Studio at C:\Android\Android Studio
    • Flutter plugin version 47.1.2
    • Dart plugin version 193.7361
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)

[√] VS Code (version 1.51.1)
    • VS Code at C:\Users\Jamal\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.17.0

[√] Connected device (1 available)
    • Android SDK built for x86 (mobile) • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

• No issues found!

neskvpey

neskvpey1#

在Flutter 3.3.0上使用onGenerateRoute时遇到了同样的问题,但没有上面提到的任何事情。通过在MaterialApp上添加主页解决了这个问题

mftmpeh8

mftmpeh82#

我找到了罪魁祸首,它是DevicePreview导致执行runApp热重载。我不知道为什么,因为它现在工作正常。我已经删除了它。

vmpqdwk3

vmpqdwk33#

正如我在你的代码中看到的,你在一个FutureBuilder中调用LocalGroceryOnline(),而你在runApp()函数中调用的FutureBuilder,所以当你尝试热重载或浏览器刷新时,它必须经过那个FutureBuilder,因为你提供的路由不会注入内存,broswer将重定向到初始路由,并显示错误:could not navigate to initial route.你应该在runApp()中有一个MaterialAppGetMaterialApp作为root,不要用futurebuilder或任何futurec函数 Package MaterialApp,这可能会导致flutter路由问题。
提示:如果你是一个用第三方插件的构建器/小部件 Package 你的MaterialApp的人,这些任务包括:路由中间件,互联网连接监听器,flavor,响应框架,screenutil,authservice等,确保小部件/构建器函数不是一个futurebuilder或futurebuilder任务,否则它会扰乱你的路由。希望它有帮助,快乐编码!

相关问题