Assert when calling a method that tries to use the ticker unsafely after dispose (#26991)

This commit is contained in:
Dan Field
2019-01-23 16:30:41 -08:00
committed by GitHub
parent 19b8d2e0a9
commit ded49cda27
2 changed files with 47 additions and 0 deletions

View File

@@ -436,6 +436,11 @@ class AnimationController extends Animation<double>
}
return true;
}());
assert(
_ticker != null,
'AnimationController.forward() called after AnimationController.dispose()\n'
'AnimationController methods should not be used after calling dispose.'
);
_direction = _AnimationDirection.forward;
if (from != null)
value = from;
@@ -464,6 +469,11 @@ class AnimationController extends Animation<double>
}
return true;
}());
assert(
_ticker != null,
'AnimationController.reverse() called after AnimationController.dispose()\n'
'AnimationController methods should not be used after calling dispose.'
);
_direction = _AnimationDirection.reverse;
if (from != null)
value = from;
@@ -483,6 +493,11 @@ class AnimationController extends Animation<double>
/// animation, when `target` is reached, [status] is reported as
/// [AnimationStatus.completed].
TickerFuture animateTo(double target, { Duration duration, Curve curve = Curves.linear }) {
assert(
_ticker != null,
'AnimationController.animateTo() called after AnimationController.dispose()\n'
'AnimationController methods should not be used after calling dispose.'
);
_direction = _AnimationDirection.forward;
return _animateToInternal(target, duration: duration, curve: curve);
}
@@ -500,6 +515,11 @@ class AnimationController extends Animation<double>
/// animation, when `target` is reached, [status] is reported as
/// [AnimationStatus.dismissed].
TickerFuture animateBack(double target, { Duration duration, Curve curve = Curves.linear }) {
assert(
_ticker != null,
'AnimationController.animateBack() called after AnimationController.dispose()\n'
'AnimationController methods should not be used after calling dispose.'
);
_direction = _AnimationDirection.reverse;
return _animateToInternal(target, duration: duration, curve: curve);
}
@@ -626,6 +646,11 @@ class AnimationController extends Animation<double>
/// canceled, meaning the future never completes and its [TickerFuture.orCancel]
/// derivative future completes with a [TickerCanceled] error.
TickerFuture animateWith(Simulation simulation) {
assert(
_ticker != null,
'AnimationController.animateWith() called after AnimationController.dispose()\n'
'AnimationController methods should not be used after calling dispose.'
);
stop();
return _startSimulation(simulation);
}
@@ -662,6 +687,11 @@ class AnimationController extends Animation<double>
/// * [forward], [reverse], [animateTo], [animateWith], [fling], and [repeat],
/// which restart the animation controller.
void stop({ bool canceled = true }) {
assert(
_ticker != null,
'AnimationController.stop() called after AnimationController.dispose()\n'
'AnimationController methods should not be used after calling dispose.'
);
_simulation = null;
_lastElapsedDuration = null;
_ticker.stop(canceled: canceled);

View File

@@ -4,6 +4,7 @@
import 'dart:ui' as ui;
import 'package:flutter/physics.dart';
import 'package:flutter/semantics.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/animation.dart';
@@ -658,4 +659,20 @@ void main() {
debugSemanticsDisableAnimations = null;
});
});
test('AnimationController methods assert _ticker is not null', () {
final AnimationController controller = AnimationController(
vsync: const TestVSync(),
);
controller.dispose();
expect(() => controller.animateBack(0), throwsAssertionError);
expect(() => controller.animateTo(0), throwsAssertionError);
expect(() => controller.animateWith(GravitySimulation(0, 0, 0, 0)), throwsAssertionError);
expect(() => controller.stop(), throwsAssertionError);
expect(() => controller.forward(), throwsAssertionError);
expect(() => controller.reverse(), throwsAssertionError);
});
}