2
2
// Use of this source code is governed by a BSD-style license that can be
3
3
// found in the LICENSE file.
4
4
5
+ import 'dart:async' ;
6
+
5
7
import 'package:meta/meta.dart' ;
6
8
import 'package:ui/ui.dart' as ui;
7
9
@@ -12,7 +14,9 @@ typedef AppLifecycleStateListener = void Function(ui.AppLifecycleState state);
12
14
13
15
/// Determines the [ui.AppLifecycleState] .
14
16
abstract class AppLifecycleState {
15
- static final AppLifecycleState instance = _BrowserAppLifecycleState ();
17
+ static AppLifecycleState create (FlutterViewManager viewManager) {
18
+ return _BrowserAppLifecycleState (viewManager);
19
+ }
16
20
17
21
ui.AppLifecycleState get appLifecycleState => _appLifecycleState;
18
22
ui.AppLifecycleState _appLifecycleState = ui.AppLifecycleState .resumed;
@@ -56,28 +60,36 @@ abstract class AppLifecycleState {
56
60
/// browser events.
57
61
///
58
62
/// This class listens to:
59
- /// - 'beforeunload' on [DomWindow] to detect detachment,
60
63
/// - 'visibilitychange' on [DomHTMLDocument] to observe visibility changes,
61
64
/// - 'focus' and 'blur' on [DomWindow] to track application focus shifts.
62
65
class _BrowserAppLifecycleState extends AppLifecycleState {
66
+ _BrowserAppLifecycleState (this ._viewManager);
67
+
68
+ final FlutterViewManager _viewManager;
69
+ final List <StreamSubscription <void >> _subscriptions = < StreamSubscription <void >> [];
70
+
63
71
@override
64
72
void activate () {
65
73
domWindow.addEventListener ('focus' , _focusListener);
66
74
domWindow.addEventListener ('blur' , _blurListener);
67
- // TODO(web): Register 'beforeunload' only if lifecycle listeners exist, to improve efficiency: https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#usage_notes
68
- domWindow.addEventListener ('beforeunload' , _beforeUnloadListener);
69
75
domDocument.addEventListener ('visibilitychange' , _visibilityChangeListener);
76
+ _subscriptions
77
+ ..add (_viewManager.onViewCreated.listen (_onViewCountChanged))
78
+ ..add (_viewManager.onViewDisposed.listen (_onViewCountChanged));
70
79
}
71
80
72
81
@override
73
82
void deactivate () {
74
83
domWindow.removeEventListener ('focus' , _focusListener);
75
84
domWindow.removeEventListener ('blur' , _blurListener);
76
- domWindow.removeEventListener ('beforeunload' , _beforeUnloadListener);
77
85
domDocument.removeEventListener (
78
86
'visibilitychange' ,
79
87
_visibilityChangeListener,
80
88
);
89
+ for (final StreamSubscription <void > subscription in _subscriptions) {
90
+ subscription.cancel ();
91
+ }
92
+ _subscriptions.clear ();
81
93
}
82
94
83
95
late final DomEventListener _focusListener =
@@ -90,11 +102,6 @@ class _BrowserAppLifecycleState extends AppLifecycleState {
90
102
onAppLifecycleStateChange (ui.AppLifecycleState .inactive);
91
103
});
92
104
93
- late final DomEventListener _beforeUnloadListener =
94
- createDomEventListener ((DomEvent event) {
95
- onAppLifecycleStateChange (ui.AppLifecycleState .detached);
96
- });
97
-
98
105
late final DomEventListener _visibilityChangeListener =
99
106
createDomEventListener ((DomEvent event) {
100
107
if (domDocument.visibilityState == 'visible' ) {
@@ -103,4 +110,12 @@ class _BrowserAppLifecycleState extends AppLifecycleState {
103
110
onAppLifecycleStateChange (ui.AppLifecycleState .hidden);
104
111
}
105
112
});
113
+
114
+ void _onViewCountChanged (_) {
115
+ if (_viewManager.views.isEmpty) {
116
+ onAppLifecycleStateChange (ui.AppLifecycleState .detached);
117
+ } else {
118
+ onAppLifecycleStateChange (ui.AppLifecycleState .resumed);
119
+ }
120
+ }
106
121
}
0 commit comments