-
-
Notifications
You must be signed in to change notification settings - Fork 615
Description
Description
ScreenDummyLayoutHelper causes an Activity memory leak on Android because it holds strong references to dummy layout views (CoordinatorLayout, AppBarLayout, Toolbar, View) that are created with an Activity-based Context, but these references are never released when the Activity is destroyed.
The root cause is a combination of flawed lifecycle management:
lateinit varprevents nullability — The view fields uselateinit var, making it impossible to set them tonullfor cleanup.- Lifecycle listener is conditionally registered — In the constructor,
addLifecycleEventListeneris only called ifmaybeInitDummyLayoutWithHeaderfails. If it succeeds (the common case),onHostDestroyis never invoked. - Listener is removed prematurely in
onHostResume— After successful initialization,removeLifecycleEventListeneris called, preventingonHostDestroyfrom firing on subsequent Activity destruction. onHostDestroydoes not release view references — Even when called, it only removes the lifecycle listener and does not null out the view fields.
This results in a reference chain: ScreenDummyLayoutHelper → Views → ContextThemeWrapper → Activity, preventing the destroyed Activity (and its entire view hierarchy, resources, and window) from being garbage collected.
Expected behavior: When the host Activity is destroyed, all view references in ScreenDummyLayoutHelper should be released so the Activity can be garbage collected. On the next onHostResume, the helper should re-initialize with the new Activity's context.
Steps to reproduce
- Create a React Native app with react-native-screens using native stack navigation.
- Navigate through several screens to ensure ScreenDummyLayoutHelper is initialized (it measures header heights via dummy layout).
- Trigger an Activity recreation — this can happen via:
- React Native dev reload (Fast Refresh / full reload)
- Android configuration change (e.g., locale change, dark mode toggle) if Activity is recreated
- Process death and restoration by the OS
- Use Android Studio Memory Profiler or LeakCanary to inspect retained objects.
- Observe that the previous Activity instance is retained in memory, held by ScreenDummyLayoutHelper's view fields (coordinatorLayout, appBarLayout, toolbar, dummyContentView).
- Repeat steps 3-5 to see the leak accumulate with each Activity recreation.
Snack or a link to a repository
(Will provide a minimal reproduction repository)
Screens version
4.23.0
React Native version
0.84.0
Platforms
Android
JavaScript runtime
Hermes
Workflow
React Native (without Expo)
Architecture
Fabric (New Architecture)
Build type
Release mode
Device
Real device
Device model
Multiple Android devices (Android 12+)
Acknowledgements
Yes