Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
4fc78b93
Unverified
Commit
4fc78b93
authored
Apr 06, 2023
by
Gregory Conrad
Committed by
GitHub
Apr 06, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix a memory leak in `AutomaticKeepAlive` (#124163)
Fix a memory leak in `AutomaticKeepAlive`
parent
509c2dde
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
46 additions
and
1 deletion
+46
-1
automatic_keep_alive.dart
packages/flutter/lib/src/widgets/automatic_keep_alive.dart
+3
-1
automatic_keep_alive_test.dart
packages/flutter/test/widgets/automatic_keep_alive_test.dart
+43
-0
No files found.
packages/flutter/lib/src/widgets/automatic_keep_alive.dart
View file @
4fc78b93
...
...
@@ -144,7 +144,8 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
}
VoidCallback
_createCallback
(
Listenable
handle
)
{
return
()
{
late
final
VoidCallback
callback
;
return
callback
=
()
{
assert
(()
{
if
(!
mounted
)
{
throw
FlutterError
(
...
...
@@ -157,6 +158,7 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
return
true
;
}());
_handles
!.
remove
(
handle
);
handle
.
removeListener
(
callback
);
if
(
_handles
!.
isEmpty
)
{
if
(
SchedulerBinding
.
instance
.
schedulerPhase
.
index
<
SchedulerPhase
.
persistentCallbacks
.
index
)
{
// Build/layout haven't started yet so let's just schedule this for
...
...
packages/flutter/test/widgets/automatic_keep_alive_test.dart
View file @
4fc78b93
...
...
@@ -557,6 +557,26 @@ void main() {
expect
(
alternate
.
children
.
length
,
1
);
});
testWidgets
(
'Keep alive Listenable has its listener removed once called'
,
(
WidgetTester
tester
)
async
{
final
LeakCheckerHandle
handle
=
LeakCheckerHandle
();
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
ListView
.
builder
(
itemCount:
1
,
itemBuilder:
(
BuildContext
context
,
int
index
)
{
return
const
KeepAliveListenableLeakChecker
(
key:
GlobalObjectKey
<
_KeepAliveListenableLeakCheckerState
>(
0
));
},
),
));
final
_KeepAliveListenableLeakCheckerState
state
=
const
GlobalObjectKey
<
_KeepAliveListenableLeakCheckerState
>(
0
).
currentState
!;
expect
(
handle
.
hasListeners
,
false
);
state
.
dispatch
(
handle
);
expect
(
handle
.
hasListeners
,
true
);
handle
.
notifyListeners
();
expect
(
handle
.
hasListeners
,
false
);
});
}
class
_AlwaysKeepAlive
extends
StatefulWidget
{
...
...
@@ -633,3 +653,26 @@ class RenderSliverMultiBoxAdaptorAlt extends RenderSliver with
@override
void
performLayout
()
{
}
}
class
LeakCheckerHandle
with
ChangeNotifier
{
@override
bool
get
hasListeners
=>
super
.
hasListeners
;
}
class
KeepAliveListenableLeakChecker
extends
StatefulWidget
{
const
KeepAliveListenableLeakChecker
({
super
.
key
});
@override
State
<
KeepAliveListenableLeakChecker
>
createState
()
=>
_KeepAliveListenableLeakCheckerState
();
}
class
_KeepAliveListenableLeakCheckerState
extends
State
<
KeepAliveListenableLeakChecker
>
{
void
dispatch
(
Listenable
handle
)
{
KeepAliveNotification
(
handle
).
dispatch
(
context
);
}
@override
Widget
build
(
BuildContext
context
)
{
return
const
Placeholder
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment