Fix ios black screen during splash screen if widget binding initializ… (#52913)
This commit is contained in:
parent
602ac0bc10
commit
9f4e5ad9c3
@ -774,7 +774,7 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
|
|||||||
/// * [scheduleWarmUpFrame], which ignores the "Vsync" signal entirely and
|
/// * [scheduleWarmUpFrame], which ignores the "Vsync" signal entirely and
|
||||||
/// triggers a frame immediately.
|
/// triggers a frame immediately.
|
||||||
void scheduleFrame() {
|
void scheduleFrame() {
|
||||||
if (_hasScheduledFrame || !_framesEnabled)
|
if (_hasScheduledFrame || !framesEnabled)
|
||||||
return;
|
return;
|
||||||
assert(() {
|
assert(() {
|
||||||
if (debugPrintScheduleFrameStacks)
|
if (debugPrintScheduleFrameStacks)
|
||||||
@ -808,7 +808,7 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
|
|||||||
void scheduleForcedFrame() {
|
void scheduleForcedFrame() {
|
||||||
// TODO(chunhtai): Removes the if case once the issue is fixed
|
// TODO(chunhtai): Removes the if case once the issue is fixed
|
||||||
// https://github.com/flutter/flutter/issues/45131
|
// https://github.com/flutter/flutter/issues/45131
|
||||||
if (!_framesEnabled)
|
if (!framesEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_hasScheduledFrame)
|
if (_hasScheduledFrame)
|
||||||
|
@ -907,6 +907,11 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
|
|||||||
Element get renderViewElement => _renderViewElement;
|
Element get renderViewElement => _renderViewElement;
|
||||||
Element _renderViewElement;
|
Element _renderViewElement;
|
||||||
|
|
||||||
|
bool _readyToProduceFrames = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get framesEnabled => super.framesEnabled && _readyToProduceFrames;
|
||||||
|
|
||||||
/// Schedules a [Timer] for attaching the root widget.
|
/// Schedules a [Timer] for attaching the root widget.
|
||||||
///
|
///
|
||||||
/// This is called by [runApp] to configure the widget tree. Consider using
|
/// This is called by [runApp] to configure the widget tree. Consider using
|
||||||
@ -928,6 +933,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
|
|||||||
/// * [RenderObjectToWidgetAdapter.attachToRenderTree], which inflates a
|
/// * [RenderObjectToWidgetAdapter.attachToRenderTree], which inflates a
|
||||||
/// widget and attaches it to the render tree.
|
/// widget and attaches it to the render tree.
|
||||||
void attachRootWidget(Widget rootWidget) {
|
void attachRootWidget(Widget rootWidget) {
|
||||||
|
_readyToProduceFrames = true;
|
||||||
_renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
|
_renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
|
||||||
container: renderView,
|
container: renderView,
|
||||||
debugShortDescription: '[root]',
|
debugShortDescription: '[root]',
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('Can only schedule frames after widget binding attaches the root widget', () async {
|
||||||
|
final WidgetsBinding binding = WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
expect(SchedulerBinding.instance.framesEnabled, isFalse);
|
||||||
|
expect(SchedulerBinding.instance.hasScheduledFrame, isFalse);
|
||||||
|
// Sends a message to notify that the engine is ready to accept frames.
|
||||||
|
final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
||||||
|
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
|
|
||||||
|
// Enables the semantics should not schedule any frames if the root widget
|
||||||
|
// has not been attached.
|
||||||
|
binding.setSemanticsEnabled(true);
|
||||||
|
expect(SchedulerBinding.instance.framesEnabled, isFalse);
|
||||||
|
expect(SchedulerBinding.instance.hasScheduledFrame, isFalse);
|
||||||
|
|
||||||
|
// The widget binding should be ready to produce frames after it attaches
|
||||||
|
// the root widget.
|
||||||
|
binding.attachRootWidget(const Placeholder());
|
||||||
|
expect(SchedulerBinding.instance.framesEnabled, isTrue);
|
||||||
|
expect(SchedulerBinding.instance.hasScheduledFrame, isTrue);
|
||||||
|
});
|
||||||
|
}
|
@ -28,6 +28,9 @@ void main() {
|
|||||||
final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
||||||
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
|
|
||||||
|
// A frame can only be scheduled when there is a root widget.
|
||||||
|
binding.attachRootWidget(const Placeholder());
|
||||||
|
|
||||||
// Frame callbacks are registered lazily when a frame is scheduled.
|
// Frame callbacks are registered lazily when a frame is scheduled.
|
||||||
binding.scheduleFrame();
|
binding.scheduleFrame();
|
||||||
expect(window.onBeginFrame, isNotNull);
|
expect(window.onBeginFrame, isNotNull);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user