Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: 启动不了 #2106

Closed
rgmyyw opened this issue Aug 5, 2024 · 9 comments
Closed

[Bug]: 启动不了 #2106

rgmyyw opened this issue Aug 5, 2024 · 9 comments

Comments

@rgmyyw
Copy link

rgmyyw commented Aug 5, 2024

请描述遇到的问题,以及您所期望的正确的结果

日志如下

lutter: FlutterBoost_dart#_restoreStackForHotRestart, [1722838332187_/], {1722838332187_/: Instance of 'FlutterContainer'}
flutter: FlutterBoost_dart#_saveStackForHotRestart, [1722838338027_/], {1722838338027_/: Instance of 'FlutterContainer'}

════════ Exception caught by scheduler library ═════════════════════════════════
The following assertion was thrown during a scheduler callback:
Please check if the engine has been initialized!
'package:flutter_boost/src/boost_channel.dart':
Failed assertion: line 37 pos 9: '_appState != null'

When the exception was thrown, this was the stack:
#2      BoostChannel.addEventListener (package:flutter_boost/src/boost_channel.dart:37:9)
boost_channel.dart:37
#3      FlutterBoostAppState._addAppLifecycleStateEventListener (package:flutter_boost/src/flutter_boost_app.dart:130:10)
flutter_boost_app.dart:130
#4      FlutterBoostAppState.initState.<anonymous closure> (package:flutter_boost/src/flutter_boost_app.dart:119:7)
flutter_boost_app.dart:119
#5      SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1392:15)
binding.dart:1392
#6      SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1326:11)
binding.dart:1326
#7      SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:1035:9)
binding.dart:1035
#8      PlatformDispatcher.scheduleWarmUpFrame.<anonymous closure> (dart:ui/platform_dispatcher.dart:837:16)
platform_dispatcher.dart:837
#19     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
isolate_patch.dart:184
(elided 12 frames from class _AssertionError, class _Timer, dart:async, and dart:async-patch)
════════════════════════════════════════════════════════════════════════════════
Restarted application in 826ms.
flutter: startup parameters []
flutter: FlutterBoost_dart#boost_flutter_binding: handleAppLifecycleStateChanged AppLifecycleState.resumed
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Localization initialized<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Start<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Init state<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Build<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Init Localization Delegate<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Init provider<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Load Localization Delegate<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Load asset from assets/langs<…>
flutter: FlutterBoost_dart#Oops, Failed to update overlay. mode=BoostSpecificEntryRefreshMode.add, BoostContainer(name:/, pages:[BoostPage<dynamic>(name:/, uniqueId:1722838341633_/, arguments:null)])


请说明如何操作会遇到上述问题

No response

在下面填入关键复现代码



class AppFlutterBinding extends WidgetsFlutterBinding
    with BoostFlutterBinding {}


 AppFlutterBinding();
 await EasyLocalization.ensureInitialized();

  Widget _easyLocalization(BuildContext context) {
    return EasyLocalization(
      fallbackLocale: const Locale('en'),
      supportedLocales: LanguageBloc.supportedLocales,
      path: 'assets/langs',
      child: Builder(builder: (context) {
        return _flutterBoost(context);
      }),
    );
  }

Widget _flutterBoost(BuildContext context) {
    return FlutterBoostApp(routeFactory, appBuilder: (home) {
      return MaterialApp(
        navigatorKey: navigatorKey,
        home: home,
        theme: themeData,
        debugShowCheckedModeBanner: false,
        builder: (_, __) => _installpendencies(context, home),
        localizationsDelegates: context.localizationDelegates,
        supportedLocales: context.supportedLocales,
        locale: context.locale,
      );
    });
  }

复现的平台

Both

Flutter SDK版本

3.22.2

FlutterBoost版本

4.6.2

是否延迟初始化FlutterBoost

No

解决方案

No response

@joechan-cq
Copy link
Collaborator

joechan-cq commented Aug 5, 2024

这种情况是不是基本出现在,app启动第一个页面就显示Flutter页面的时候?

@0xZOne @imcjj 是否可以考虑将FlutterBoostAppState.initState中的addPostFrameCallback的逻辑,移动到didChangeDependencies中去,确保mount之后再执行?

#1719

@rgmyyw
Copy link
Author

rgmyyw commented Aug 6, 2024

控制台日志


Restarted application in 886ms.
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Start<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Init state<…>
flutter: \^[[32m[🌎 Easy Localization] [INFO] Start locale loaded en<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Build<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Init Localization Delegate<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Init provider<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Load Localization Delegate<…>
flutter: \^[[90m[🌎 Easy Localization] [DEBUG] Load asset from assets/langs<…>
flutter: FlutterBoost_dart#Oops, Failed to update overlay. mode=BoostSpecificEntryRefreshMode.add, BoostContainer(name:mainPage, pages:[BoostPage<dynamic>(name:mainPage, uniqueId:1722911603470_mainPage, arguments:null)])

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';

void main() {
  ///这里的CustomFlutterBinding调用务必不可缺少,用于控制Boost状态的resume和pause
  CustomFlutterBinding();

  final List<Locale> supportedLocales = [
    const Locale('en'),
    const Locale('zh'),
    const Locale('ar'),
  ];

  const fallbackLocale = Locale('en');

  runApp(EasyLocalization(
    fallbackLocale: fallbackLocale,
    supportedLocales: supportedLocales,
    startLocale: const Locale('en'),
    path: 'assets/langs',
    child: const MyApp(),
  ));
}

class CustomFlutterBinding extends WidgetsFlutterBinding
    with BoostFlutterBinding {}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  /// 由于很多同学说没有跳转动画,这里是因为之前exmaple里面用的是 [PageRouteBuilder]
  /// 其实这里是可以自定义的,和Boost没太多关系,比如我想用类似iOS平台的动画,
  /// 那么只需要像下面这样写成 [CupertinoPageRoute] 即可
  /// (这里全写成[MaterialPageRoute]也行,这里只不过用[CupertinoPageRoute]举例子)
  ///
  /// 注意,如果需要push的时候,两个页面都需要动的话,
  /// (就是像iOS native那样,在push的时候,前面一个页面也会向左推一段距离)
  /// 那么前后两个页面都必须是遵循CupertinoRouteTransitionMixin的路由
  /// 简单来说,就两个页面都是CupertinoPageRoute就好
  /// 如果用MaterialPageRoute的话同理

  Map<String, FlutterBoostRouteFactory> routerMap = {
    'mainPage': (RouteSettings settings, String? uniqueId) {
      return CupertinoPageRoute(
          settings: settings,
          builder: (_) {
            // Map<String, Object>? map = settings.arguments as Map<String, Object>;
            // String data = map['data'] as String;
            return const MainPage(
              data: '123',
            );
          });
    },
    'simplePage': (settings, uniqueId) {
      return CupertinoPageRoute(
          settings: settings,
          builder: (_) {
            Map<String, Object> map = settings.arguments as Map<String, Object>;
            String data = map['data'] as String;
            return SimplePage(
              data: data,
            );
          });
    },
  };

  Route<dynamic>? routeFactory(RouteSettings settings, String? uniqueId) {
    FlutterBoostRouteFactory func =
        routerMap[settings.name] as FlutterBoostRouteFactory;
    return func(settings, uniqueId);
  }

  Widget appBuilder(Widget home) {
    return MaterialApp(
      home: home,
      debugShowCheckedModeBanner: true,

      /// 这三行注释,  就可以
      localizationsDelegates: context.localizationDelegates,
      supportedLocales: context.supportedLocales,
      locale: context.locale,

      ///必须加上builder参数,否则showDialog等会出问题
      builder: (_, __) {
        return home;
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return FlutterBoostApp(routeFactory,
        appBuilder: appBuilder, initialRoute: 'mainPage');
  }
}

class MainPage extends StatelessWidget {
  const MainPage({super.key, required Object data});
  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(child: Text('Main Page')),
    );
  }
}

class SimplePage extends StatelessWidget {
  const SimplePage({super.key, required Object data});
  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(child: Text('SimplePage')),
    );
  }
}

@rgmyyw
Copy link
Author

rgmyyw commented Aug 6, 2024

@joechan-cq
Copy link
Collaborator

的确问题出在MaterialApp中对locale的设置上,设置了这个会对应添加Localizations的Widget,而它的build方法:
image
必须在加载完_locale后才会把MaterialApphome给挂载上去,加载locale这个是个Future任务,因此导致FlutterBoost初始化的时序出现了问题。

joechan-cq added a commit to joechan-cq/flutter_boost that referenced this issue Aug 6, 2024
将原先在initState中进行的初始化,改放到确保Overlay被mounted之后的时序中
@imcjj
Copy link
Collaborator

imcjj commented Aug 8, 2024

@rgmyyw 关于这个问题,内部讨论了下,确实是boost的一个潜在bug,但是考虑到修改的话会影响到维护人员后续对boost内部关键逻辑的理解,并且按照boost的标准用法的话(initRoute本身不应该有业务意义),这个问题并不会影响应用正常使用,所以不考虑将该问题修复。如果题主自身业务中该问题有较大影响,建议自行拉分支修复后以自用,修复方法参考该PR: #2108

@joechan-cq
Copy link
Collaborator

@rgmyyw 关于这个问题,内部讨论了下,确实是boost的一个潜在bug,但是考虑到修改的话会影响到维护人员后续对boost内部关键逻辑的理解,并且按照boost的标准用法的话(initRoute本身不应该有业务意义),这个问题并不会影响应用正常使用,所以不考虑将该问题修复。如果题主自身业务中该问题有较大影响,建议自行拉分支修复后以自用,修复方法参考该PR: #2108

这单纯就是Boost框架的问题吧,和initRoute也没关系,只是对MaterialApp中设置了locale后没做好兼容的问题。

而且为什么会有内部关键逻辑理解产生问题?关键逻辑没变吧,一直都是启动时获取已经挂载的Overlay然后做后续初始化,现在的PR也只是确保初始化时Overlay一定被挂载了。

@imcjj
Copy link
Collaborator

imcjj commented Aug 8, 2024

@joechan-cq 这边建议可以自行拉分支修复~~主仓库暂不考虑修复哈

@kavin-zhihua
Copy link

@joechan-cq 这边建议可以自行拉分支修复~~主仓库暂不考虑修复哈

我混合项目使用了flutter_screenutil,也是必白屏,去掉就不会了

@joechan-cq
Copy link
Collaborator

@joechan-cq 这边建议可以自行拉分支修复~~主仓库暂不考虑修复哈

我混合项目使用了flutter_screenutil,也是必白屏,去掉就不会了

如果报错也是一样的,那原因应该也一样,screenutil的build方法,内部有延迟挂载的逻辑。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants