mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
Inspector robustness fixes. (#14154)
* Inspector robustness fixes. Avoid cases where setState was called on disposed object. Avoid cases where the inspector wouldn't render as it was called after the first frame rendered and no other frames were rendered.
This commit is contained in:
parent
460dd00b72
commit
2e4522f7ec
|
@ -474,6 +474,15 @@ abstract class WidgetsBinding extends BindingBase with SchedulerBinding, Gesture
|
|||
int _deferFirstFrameReportCount = 0;
|
||||
bool get _reportFirstFrame => _deferFirstFrameReportCount == 0;
|
||||
|
||||
/// Whether the first frame has finished rendering.
|
||||
///
|
||||
/// Only valid in profile and debug builds, it can't be used in release
|
||||
/// builds.
|
||||
/// It can be deferred using [deferFirstFrameReport] and
|
||||
/// [allowFirstFrameReport].
|
||||
/// The value is set at the end of the call to [drawFrame].
|
||||
bool get debugDidSendFirstFrameEvent => !_needToReportFirstFrame;
|
||||
|
||||
/// Tell the framework not to report the frame it is building as a "useful"
|
||||
/// first frame until there is a corresponding call to [allowFirstFrameReport].
|
||||
///
|
||||
|
|
|
@ -12,6 +12,7 @@ import 'dart:ui' show Offset;
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
|
||||
import 'basic.dart';
|
||||
import 'binding.dart';
|
||||
|
@ -200,6 +201,13 @@ class WidgetInspectorService {
|
|||
return id;
|
||||
}
|
||||
|
||||
/// Returns whether the application has rendered its first frame and it is
|
||||
/// appropriate to display the Widget tree in the inspector.
|
||||
bool isWidgetTreeReady([String groupName]) {
|
||||
return WidgetsBinding.instance != null &&
|
||||
WidgetsBinding.instance.debugDidSendFirstFrameEvent;
|
||||
}
|
||||
|
||||
/// Returns the Dart object associated with a reference id.
|
||||
///
|
||||
/// The `groupName` parameter is not required by is added to regularize the
|
||||
|
@ -210,8 +218,9 @@ class WidgetInspectorService {
|
|||
return null;
|
||||
|
||||
final _InspectorReferenceData data = _idToReferenceData[id];
|
||||
if (data == null)
|
||||
throw new FlutterError('Id does not exist');
|
||||
if (data == null) {
|
||||
throw new FlutterError('Id does not exist.');
|
||||
}
|
||||
return data.object;
|
||||
}
|
||||
|
||||
|
@ -281,7 +290,16 @@ class WidgetInspectorService {
|
|||
selection.current = object;
|
||||
}
|
||||
if (selectionChangedCallback != null) {
|
||||
selectionChangedCallback();
|
||||
if (WidgetsBinding.instance.schedulerPhase == SchedulerPhase.idle) {
|
||||
selectionChangedCallback();
|
||||
} else {
|
||||
// It isn't safe to trigger the selection change callback if we are in
|
||||
// the middle of rendering the frame.
|
||||
SchedulerBinding.instance.scheduleTask(
|
||||
selectionChangedCallback,
|
||||
Priority.touch,
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -467,15 +485,27 @@ class _WidgetInspectorState extends State<WidgetInspector>
|
|||
/// as selecting the edge of the bounding box.
|
||||
static const double _kEdgeHitMargin = 2.0;
|
||||
|
||||
InspectorSelectionChangedCallback _selectionChangedCallback;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetInspectorService.instance.selectionChangedCallback = () {
|
||||
|
||||
_selectionChangedCallback = () {
|
||||
setState(() {
|
||||
// The [selection] property which the build method depends on has
|
||||
// changed.
|
||||
});
|
||||
};
|
||||
assert(WidgetInspectorService.instance.selectionChangedCallback == null);
|
||||
WidgetInspectorService.instance.selectionChangedCallback = _selectionChangedCallback;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
if (WidgetInspectorService.instance.selectionChangedCallback == _selectionChangedCallback) {
|
||||
WidgetInspectorService.instance.selectionChangedCallback = null;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
bool _hitTestHelper(
|
||||
|
|
Loading…
Reference in a new issue